Spaces:
Running
Running
class t{constructor(t=0,F=0,U=0){this.x=t,this.y=F,this.z=U}equals(t){return this.x===t.x&&(this.y===t.y&&this.z===t.z)}add(F){return"number"==typeof F?new t(this.x+F,this.y+F,this.z+F):new t(this.x+F.x,this.y+F.y,this.z+F.z)}subtract(F){return"number"==typeof F?new t(this.x-F,this.y-F,this.z-F):new t(this.x-F.x,this.y-F.y,this.z-F.z)}multiply(F){return"number"==typeof F?new t(this.x*F,this.y*F,this.z*F):F instanceof t?new t(this.x*F.x,this.y*F.y,this.z*F.z):new t(this.x*F.buffer[0]+this.y*F.buffer[4]+this.z*F.buffer[8]+F.buffer[12],this.x*F.buffer[1]+this.y*F.buffer[5]+this.z*F.buffer[9]+F.buffer[13],this.x*F.buffer[2]+this.y*F.buffer[6]+this.z*F.buffer[10]+F.buffer[14])}divide(F){return"number"==typeof F?new t(this.x/F,this.y/F,this.z/F):new t(this.x/F.x,this.y/F.y,this.z/F.z)}cross(F){const U=this.y*F.z-this.z*F.y,l=this.z*F.x-this.x*F.z,n=this.x*F.y-this.y*F.x;return new t(U,l,n)}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lerp(F,U){return new t(this.x+(F.x-this.x)*U,this.y+(F.y-this.y)*U,this.z+(F.z-this.z)*U)}min(F){return new t(Math.min(this.x,F.x),Math.min(this.y,F.y),Math.min(this.z,F.z))}max(F){return new t(Math.max(this.x,F.x),Math.max(this.y,F.y),Math.max(this.z,F.z))}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error(`Invalid component index: ${t}`)}}minComponent(){return this.x<this.y&&this.x<this.z?0:this.y<this.z?1:2}maxComponent(){return this.x>this.y&&this.x>this.z?0:this.y>this.z?1:2}magnitude(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}distanceTo(t){return Math.sqrt((this.x-t.x)**2+(this.y-t.y)**2+(this.z-t.z)**2)}normalize(){const F=this.magnitude();return new t(this.x/F,this.y/F,this.z/F)}flat(){return[this.x,this.y,this.z]}clone(){return new t(this.x,this.y,this.z)}toString(){return`[${this.flat().join(", ")}]`}static One(F=1){return new t(F,F,F)}}class F{constructor(t=0,F=0,U=0,l=1){this.x=t,this.y=F,this.z=U,this.w=l}equals(t){return this.x===t.x&&(this.y===t.y&&(this.z===t.z&&this.w===t.w))}normalize(){const t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);return new F(this.x/t,this.y/t,this.z/t,this.w/t)}multiply(t){const U=this.w,l=this.x,n=this.y,Q=this.z,e=t.w,d=t.x,A=t.y,B=t.z;return new F(U*d+l*e+n*B-Q*A,U*A-l*B+n*e+Q*d,U*B+l*A-n*d+Q*e,U*e-l*d-n*A-Q*B)}inverse(){const t=this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w;return new F(-this.x/t,-this.y/t,-this.z/t,this.w/t)}apply(U){const l=new F(U.x,U.y,U.z,0),n=new F(-this.x,-this.y,-this.z,this.w),Q=this.multiply(l).multiply(n);return new t(Q.x,Q.y,Q.z)}flat(){return[this.x,this.y,this.z,this.w]}clone(){return new F(this.x,this.y,this.z,this.w)}static FromEuler(t){const U=t.x/2,l=t.y/2,n=t.z/2,Q=Math.cos(l),e=Math.sin(l),d=Math.cos(U),A=Math.sin(U),B=Math.cos(n),a=Math.sin(n);return new F(Q*A*B+e*d*a,e*d*B-Q*A*a,Q*d*a-e*A*B,Q*d*B+e*A*a)}toEuler(){const F=2*(this.w*this.x+this.y*this.z),U=1-2*(this.x*this.x+this.y*this.y),l=Math.atan2(F,U);let n;const Q=2*(this.w*this.y-this.z*this.x);n=Math.abs(Q)>=1?Math.sign(Q)*Math.PI/2:Math.asin(Q);const e=2*(this.w*this.z+this.x*this.y),d=1-2*(this.y*this.y+this.z*this.z),A=Math.atan2(e,d);return new t(l,n,A)}static FromMatrix3(t){const U=t.buffer,l=U[0]+U[4]+U[8];let n,Q,e,d;if(l>0){const t=.5/Math.sqrt(l+1);d=.25/t,n=(U[7]-U[5])*t,Q=(U[2]-U[6])*t,e=(U[3]-U[1])*t}else if(U[0]>U[4]&&U[0]>U[8]){const t=2*Math.sqrt(1+U[0]-U[4]-U[8]);d=(U[7]-U[5])/t,n=.25*t,Q=(U[1]+U[3])/t,e=(U[2]+U[6])/t}else if(U[4]>U[8]){const t=2*Math.sqrt(1+U[4]-U[0]-U[8]);d=(U[2]-U[6])/t,n=(U[1]+U[3])/t,Q=.25*t,e=(U[5]+U[7])/t}else{const t=2*Math.sqrt(1+U[8]-U[0]-U[4]);d=(U[3]-U[1])/t,n=(U[2]+U[6])/t,Q=(U[5]+U[7])/t,e=.25*t}return new F(n,Q,e,d)}static FromAxisAngle(t,U){const l=U/2,n=Math.sin(l),Q=Math.cos(l);return new F(t.x*n,t.y*n,t.z*n,Q)}static LookRotation(U){const l=new t(0,0,1),n=l.dot(U);if(Math.abs(n- -1)<1e-6)return new F(0,1,0,Math.PI);if(Math.abs(n-1)<1e-6)return new F;const Q=Math.acos(n),e=l.cross(U).normalize();return F.FromAxisAngle(e,Q)}toString(){return`[${this.flat().join(", ")}]`}}class U{constructor(){const t=new Map;this.addEventListener=(F,U)=>{t.has(F)||t.set(F,new Set),t.get(F).add(U)},this.removeEventListener=(F,U)=>{t.has(F)&&t.get(F).delete(U)},this.hasEventListener=(F,U)=>!!t.has(F)&&t.get(F).has(U),this.dispatchEvent=F=>{if(t.has(F.type))for(const U of t.get(F.type))U(F)}}}class l{constructor(t=1,F=0,U=0,l=0,n=0,Q=1,e=0,d=0,A=0,B=0,a=1,i=0,V=0,Z=0,R=0,c=1){this.buffer=[t,F,U,l,n,Q,e,d,A,B,a,i,V,Z,R,c]}equals(t){if(this.buffer.length!==t.buffer.length)return!1;if(this.buffer===t.buffer)return!0;for(let F=0;F<this.buffer.length;F++)if(this.buffer[F]!==t.buffer[F])return!1;return!0}multiply(t){const F=this.buffer,U=t.buffer;return new l(U[0]*F[0]+U[1]*F[4]+U[2]*F[8]+U[3]*F[12],U[0]*F[1]+U[1]*F[5]+U[2]*F[9]+U[3]*F[13],U[0]*F[2]+U[1]*F[6]+U[2]*F[10]+U[3]*F[14],U[0]*F[3]+U[1]*F[7]+U[2]*F[11]+U[3]*F[15],U[4]*F[0]+U[5]*F[4]+U[6]*F[8]+U[7]*F[12],U[4]*F[1]+U[5]*F[5]+U[6]*F[9]+U[7]*F[13],U[4]*F[2]+U[5]*F[6]+U[6]*F[10]+U[7]*F[14],U[4]*F[3]+U[5]*F[7]+U[6]*F[11]+U[7]*F[15],U[8]*F[0]+U[9]*F[4]+U[10]*F[8]+U[11]*F[12],U[8]*F[1]+U[9]*F[5]+U[10]*F[9]+U[11]*F[13],U[8]*F[2]+U[9]*F[6]+U[10]*F[10]+U[11]*F[14],U[8]*F[3]+U[9]*F[7]+U[10]*F[11]+U[11]*F[15],U[12]*F[0]+U[13]*F[4]+U[14]*F[8]+U[15]*F[12],U[12]*F[1]+U[13]*F[5]+U[14]*F[9]+U[15]*F[13],U[12]*F[2]+U[13]*F[6]+U[14]*F[10]+U[15]*F[14],U[12]*F[3]+U[13]*F[7]+U[14]*F[11]+U[15]*F[15])}clone(){const t=this.buffer;return new l(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}determinant(){const t=this.buffer;return t[12]*t[9]*t[6]*t[3]-t[8]*t[13]*t[6]*t[3]-t[12]*t[5]*t[10]*t[3]+t[4]*t[13]*t[10]*t[3]+t[8]*t[5]*t[14]*t[3]-t[4]*t[9]*t[14]*t[3]-t[12]*t[9]*t[2]*t[7]+t[8]*t[13]*t[2]*t[7]+t[12]*t[1]*t[10]*t[7]-t[0]*t[13]*t[10]*t[7]-t[8]*t[1]*t[14]*t[7]+t[0]*t[9]*t[14]*t[7]+t[12]*t[5]*t[2]*t[11]-t[4]*t[13]*t[2]*t[11]-t[12]*t[1]*t[6]*t[11]+t[0]*t[13]*t[6]*t[11]+t[4]*t[1]*t[14]*t[11]-t[0]*t[5]*t[14]*t[11]-t[8]*t[5]*t[2]*t[15]+t[4]*t[9]*t[2]*t[15]+t[8]*t[1]*t[6]*t[15]-t[0]*t[9]*t[6]*t[15]-t[4]*t[1]*t[10]*t[15]+t[0]*t[5]*t[10]*t[15]}invert(){const t=this.buffer,F=this.determinant();if(0===F)throw new Error("Matrix is not invertible.");const U=1/F;return new l(U*(t[5]*t[10]*t[15]-t[5]*t[11]*t[14]-t[9]*t[6]*t[15]+t[9]*t[7]*t[14]+t[13]*t[6]*t[11]-t[13]*t[7]*t[10]),U*(-t[1]*t[10]*t[15]+t[1]*t[11]*t[14]+t[9]*t[2]*t[15]-t[9]*t[3]*t[14]-t[13]*t[2]*t[11]+t[13]*t[3]*t[10]),U*(t[1]*t[6]*t[15]-t[1]*t[7]*t[14]-t[5]*t[2]*t[15]+t[5]*t[3]*t[14]+t[13]*t[2]*t[7]-t[13]*t[3]*t[6]),U*(-t[1]*t[6]*t[11]+t[1]*t[7]*t[10]+t[5]*t[2]*t[11]-t[5]*t[3]*t[10]-t[9]*t[2]*t[7]+t[9]*t[3]*t[6]),U*(-t[4]*t[10]*t[15]+t[4]*t[11]*t[14]+t[8]*t[6]*t[15]-t[8]*t[7]*t[14]-t[12]*t[6]*t[11]+t[12]*t[7]*t[10]),U*(t[0]*t[10]*t[15]-t[0]*t[11]*t[14]-t[8]*t[2]*t[15]+t[8]*t[3]*t[14]+t[12]*t[2]*t[11]-t[12]*t[3]*t[10]),U*(-t[0]*t[6]*t[15]+t[0]*t[7]*t[14]+t[4]*t[2]*t[15]-t[4]*t[3]*t[14]-t[12]*t[2]*t[7]+t[12]*t[3]*t[6]),U*(t[0]*t[6]*t[11]-t[0]*t[7]*t[10]-t[4]*t[2]*t[11]+t[4]*t[3]*t[10]+t[8]*t[2]*t[7]-t[8]*t[3]*t[6]),U*(t[4]*t[9]*t[15]-t[4]*t[11]*t[13]-t[8]*t[5]*t[15]+t[8]*t[7]*t[13]+t[12]*t[5]*t[11]-t[12]*t[7]*t[9]),U*(-t[0]*t[9]*t[15]+t[0]*t[11]*t[13]+t[8]*t[1]*t[15]-t[8]*t[3]*t[13]-t[12]*t[1]*t[11]+t[12]*t[3]*t[9]),U*(t[0]*t[5]*t[15]-t[0]*t[7]*t[13]-t[4]*t[1]*t[15]+t[4]*t[3]*t[13]+t[12]*t[1]*t[7]-t[12]*t[3]*t[5]),U*(-t[0]*t[5]*t[11]+t[0]*t[7]*t[9]+t[4]*t[1]*t[11]-t[4]*t[3]*t[9]-t[8]*t[1]*t[7]+t[8]*t[3]*t[5]),U*(-t[4]*t[9]*t[14]+t[4]*t[10]*t[13]+t[8]*t[5]*t[14]-t[8]*t[6]*t[13]-t[12]*t[5]*t[10]+t[12]*t[6]*t[9]),U*(t[0]*t[9]*t[14]-t[0]*t[10]*t[13]-t[8]*t[1]*t[14]+t[8]*t[2]*t[13]+t[12]*t[1]*t[10]-t[12]*t[2]*t[9]),U*(-t[0]*t[5]*t[14]+t[0]*t[6]*t[13]+t[4]*t[1]*t[14]-t[4]*t[2]*t[13]-t[12]*t[1]*t[6]+t[12]*t[2]*t[5]),U*(t[0]*t[5]*t[10]-t[0]*t[6]*t[9]-t[4]*t[1]*t[10]+t[4]*t[2]*t[9]+t[8]*t[1]*t[6]-t[8]*t[2]*t[5]))}static Compose(t,F,U){const n=F.x,Q=F.y,e=F.z,d=F.w,A=n+n,B=Q+Q,a=e+e,i=n*A,V=n*B,Z=n*a,R=Q*B,c=Q*a,s=e*a,o=d*A,r=d*B,h=d*a,W=U.x,I=U.y,m=U.z;return new l((1-(R+s))*W,(V+h)*W,(Z-r)*W,0,(V-h)*I,(1-(i+s))*I,(c+o)*I,0,(Z+r)*m,(c-o)*m,(1-(i+R))*m,0,t.x,t.y,t.z,1)}toString(){return`[${this.buffer.join(", ")}]`}}class n extends Event{constructor(t){super("objectAdded"),this.object=t}}class Q extends Event{constructor(t){super("objectRemoved"),this.object=t}}class e extends Event{constructor(t){super("objectChanged"),this.object=t}}class d extends U{constructor(){super(),this.positionChanged=!1,this.rotationChanged=!1,this.scaleChanged=!1,this._position=new t,this._rotation=new F,this._scale=new t(1,1,1),this._transform=new l,this._changeEvent=new e(this),this.update=()=>{},this.applyPosition=()=>{this.position=new t},this.applyRotation=()=>{this.rotation=new F},this.applyScale=()=>{this.scale=new t(1,1,1)},this.raiseChangeEvent=()=>{this.dispatchEvent(this._changeEvent)}}_updateMatrix(){this._transform=l.Compose(this._position,this._rotation,this._scale)}get position(){return this._position}set position(t){this._position.equals(t)||(this._position=t,this.positionChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get rotation(){return this._rotation}set rotation(t){this._rotation.equals(t)||(this._rotation=t,this.rotationChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get scale(){return this._scale}set scale(t){this._scale.equals(t)||(this._scale=t,this.scaleChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get forward(){let F=new t(0,0,1);return F=this.rotation.apply(F),F}get transform(){return this._transform}}class A{constructor(t=1,F=0,U=0,l=0,n=1,Q=0,e=0,d=0,A=1){this.buffer=[t,F,U,l,n,Q,e,d,A]}equals(t){if(this.buffer.length!==t.buffer.length)return!1;if(this.buffer===t.buffer)return!0;for(let F=0;F<this.buffer.length;F++)if(this.buffer[F]!==t.buffer[F])return!1;return!0}multiply(t){const F=this.buffer,U=t.buffer;return new A(U[0]*F[0]+U[3]*F[1]+U[6]*F[2],U[1]*F[0]+U[4]*F[1]+U[7]*F[2],U[2]*F[0]+U[5]*F[1]+U[8]*F[2],U[0]*F[3]+U[3]*F[4]+U[6]*F[5],U[1]*F[3]+U[4]*F[4]+U[7]*F[5],U[2]*F[3]+U[5]*F[4]+U[8]*F[5],U[0]*F[6]+U[3]*F[7]+U[6]*F[8],U[1]*F[6]+U[4]*F[7]+U[7]*F[8],U[2]*F[6]+U[5]*F[7]+U[8]*F[8])}clone(){const t=this.buffer;return new A(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])}static Eye(t=1){return new A(t,0,0,0,t,0,0,0,t)}static Diagonal(t){return new A(t.x,0,0,0,t.y,0,0,0,t.z)}static RotationFromQuaternion(t){return new A(1-2*t.y*t.y-2*t.z*t.z,2*t.x*t.y-2*t.z*t.w,2*t.x*t.z+2*t.y*t.w,2*t.x*t.y+2*t.z*t.w,1-2*t.x*t.x-2*t.z*t.z,2*t.y*t.z-2*t.x*t.w,2*t.x*t.z-2*t.y*t.w,2*t.y*t.z+2*t.x*t.w,1-2*t.x*t.x-2*t.y*t.y)}static RotationFromEuler(t){const F=Math.cos(t.x),U=Math.sin(t.x),l=Math.cos(t.y),n=Math.sin(t.y),Q=Math.cos(t.z),e=Math.sin(t.z);return new A(...[l*Q+n*U*e,-l*e+n*U*Q,n*F,F*e,F*Q,-U,-n*Q+l*U*e,n*e+l*U*Q,l*F])}toString(){return`[${this.buffer.join(", ")}]`}}class B{constructor(t=0,U=null,l=null,n=null,Q=null){this.changed=!1,this.detached=!1,this._vertexCount=t,this._positions=U||new Float32Array(0),this._rotations=l||new Float32Array(0),this._scales=n||new Float32Array(0),this._colors=Q||new Uint8Array(0),this._selection=new Uint8Array(this.vertexCount),this.translate=t=>{for(let F=0;F<this.vertexCount;F++)this.positions[3*F+0]+=t.x,this.positions[3*F+1]+=t.y,this.positions[3*F+2]+=t.z;this.changed=!0},this.rotate=t=>{const U=A.RotationFromQuaternion(t).buffer;for(let l=0;l<this.vertexCount;l++){const n=this.positions[3*l+0],Q=this.positions[3*l+1],e=this.positions[3*l+2];this.positions[3*l+0]=U[0]*n+U[1]*Q+U[2]*e,this.positions[3*l+1]=U[3]*n+U[4]*Q+U[5]*e,this.positions[3*l+2]=U[6]*n+U[7]*Q+U[8]*e;const d=new F(this.rotations[4*l+1],this.rotations[4*l+2],this.rotations[4*l+3],this.rotations[4*l+0]),A=t.multiply(d);this.rotations[4*l+1]=A.x,this.rotations[4*l+2]=A.y,this.rotations[4*l+3]=A.z,this.rotations[4*l+0]=A.w}this.changed=!0},this.scale=t=>{for(let F=0;F<this.vertexCount;F++)this.positions[3*F+0]*=t.x,this.positions[3*F+1]*=t.y,this.positions[3*F+2]*=t.z,this.scales[3*F+0]*=t.x,this.scales[3*F+1]*=t.y,this.scales[3*F+2]*=t.z;this.changed=!0},this.serialize=()=>{const t=new Uint8Array(this.vertexCount*B.RowLength),F=new Float32Array(t.buffer),U=new Uint8Array(t.buffer);for(let t=0;t<this.vertexCount;t++)F[8*t+0]=this.positions[3*t+0],F[8*t+1]=this.positions[3*t+1],F[8*t+2]=this.positions[3*t+2],U[32*t+24+0]=this.colors[4*t+0],U[32*t+24+1]=this.colors[4*t+1],U[32*t+24+2]=this.colors[4*t+2],U[32*t+24+3]=this.colors[4*t+3],F[8*t+3+0]=this.scales[3*t+0],F[8*t+3+1]=this.scales[3*t+1],F[8*t+3+2]=this.scales[3*t+2],U[32*t+28+0]=128*this.rotations[4*t+0]+128&255,U[32*t+28+1]=128*this.rotations[4*t+1]+128&255,U[32*t+28+2]=128*this.rotations[4*t+2]+128&255,U[32*t+28+3]=128*this.rotations[4*t+3]+128&255;return t},this.reattach=(t,F,U,l,n)=>{console.assert(t.byteLength===3*this.vertexCount*4,`Expected ${3*this.vertexCount*4} bytes, got ${t.byteLength} bytes`),this._positions=new Float32Array(t),this._rotations=new Float32Array(F),this._scales=new Float32Array(U),this._colors=new Uint8Array(l),this._selection=new Uint8Array(n),this.detached=!1}}static Deserialize(t){const F=t.length/B.RowLength,U=new Float32Array(3*F),l=new Float32Array(4*F),n=new Float32Array(3*F),Q=new Uint8Array(4*F),e=new Float32Array(t.buffer),d=new Uint8Array(t.buffer);for(let t=0;t<F;t++)U[3*t+0]=e[8*t+0],U[3*t+1]=e[8*t+1],U[3*t+2]=e[8*t+2],l[4*t+0]=(d[32*t+28+0]-128)/128,l[4*t+1]=(d[32*t+28+1]-128)/128,l[4*t+2]=(d[32*t+28+2]-128)/128,l[4*t+3]=(d[32*t+28+3]-128)/128,n[3*t+0]=e[8*t+3+0],n[3*t+1]=e[8*t+3+1],n[3*t+2]=e[8*t+3+2],Q[4*t+0]=d[32*t+24+0],Q[4*t+1]=d[32*t+24+1],Q[4*t+2]=d[32*t+24+2],Q[4*t+3]=d[32*t+24+3];return new B(F,U,l,n,Q)}get vertexCount(){return this._vertexCount}get positions(){return this._positions}get rotations(){return this._rotations}get scales(){return this._scales}get colors(){return this._colors}get selection(){return this._selection}clone(){return new B(this.vertexCount,new Float32Array(this.positions),new Float32Array(this.rotations),new Float32Array(this.scales),new Uint8Array(this.colors))}}B.RowLength=32;class a{constructor(t,F,U,l,n){this._vertexCount=t,this._positions=F,this._data=U,this._width=l,this._height=n,this.serialize=()=>new Uint8Array(this._data.buffer)}static Deserialize(t,F,U){const l=new Uint32Array(t.buffer),n=new Float32Array(t.buffer),Q=Math.floor(n.byteLength/this.RowLength),e=new Float32Array(3*Q);for(let t=0;t<Q;t++)e[3*t+0]=n[16*t+0],e[3*t+1]=n[16*t+1],e[3*t+2]=n[16*t+2],e[3*t+0]=n[16*t+3];return new a(Q,e,l,F,U)}get vertexCount(){return this._vertexCount}get positions(){return this._positions}get data(){return this._data}get width(){return this._width}get height(){return this._height}}a.RowLength=64;class i{static SplatToPLY(t,U){let l="ply\nformat binary_little_endian 1.0\n";l+=`element vertex ${U}\n`;const n=["x","y","z","nx","ny","nz","f_dc_0","f_dc_1","f_dc_2"];for(let t=0;t<45;t++)n.push(`f_rest_${t}`);n.push("opacity"),n.push("scale_0"),n.push("scale_1"),n.push("scale_2"),n.push("rot_0"),n.push("rot_1"),n.push("rot_2"),n.push("rot_3");for(const t of n)l+=`property float ${t}\n`;l+="end_header\n";const Q=(new TextEncoder).encode(l),e=248,d=U*e,A=new DataView(new ArrayBuffer(Q.length+d));new Uint8Array(A.buffer).set(Q,0);const B=new Float32Array(t),a=new Uint8Array(t),i=Q.length,V=220,Z=232;for(let t=0;t<U;t++){const U=B[8*t+0],l=B[8*t+1],n=B[8*t+2],Q=(a[32*t+24+0]/255-.5)/this.SH_C0,d=(a[32*t+24+1]/255-.5)/this.SH_C0,R=(a[32*t+24+2]/255-.5)/this.SH_C0,c=a[32*t+24+3]/255,s=Math.log(c/(1-c)),o=Math.log(B[8*t+3+0]),r=Math.log(B[8*t+3+1]),h=Math.log(B[8*t+3+2]);let W=new F((a[32*t+28+1]-128)/128,(a[32*t+28+2]-128)/128,(a[32*t+28+3]-128)/128,(a[32*t+28+0]-128)/128);W=W.normalize();const I=W.w,m=W.x,b=W.y,J=W.z;A.setFloat32(i+e*t+0,U,!0),A.setFloat32(i+e*t+4,l,!0),A.setFloat32(i+e*t+8,n,!0),A.setFloat32(i+e*t+24+0,Q,!0),A.setFloat32(i+e*t+24+4,d,!0),A.setFloat32(i+e*t+24+8,R,!0),A.setFloat32(i+e*t+216,s,!0),A.setFloat32(i+e*t+V+0,o,!0),A.setFloat32(i+e*t+V+4,r,!0),A.setFloat32(i+e*t+V+8,h,!0),A.setFloat32(i+e*t+Z+0,I,!0),A.setFloat32(i+e*t+Z+4,m,!0),A.setFloat32(i+e*t+Z+8,b,!0),A.setFloat32(i+e*t+Z+12,J,!0)}return A.buffer}}i.SH_C0=.28209479177387814;class V{constructor(t,F){this.min=t,this.max=F}contains(t){return t.x>=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}intersects(t){return this.max.x>=t.min.x&&this.min.x<=t.max.x&&this.max.y>=t.min.y&&this.min.y<=t.max.y&&this.max.z>=t.min.z&&this.min.z<=t.max.z}size(){return this.max.subtract(this.min)}center(){return this.min.add(this.max).divide(2)}expand(t){this.min=this.min.min(t),this.max=this.max.max(t)}permute(){const F=this.min,U=this.max;this.min=new t(Math.min(F.x,U.x),Math.min(F.y,U.y),Math.min(F.z,U.z)),this.max=new t(Math.max(F.x,U.x),Math.max(F.y,U.y),Math.max(F.z,U.z))}}class Z extends d{constructor(U=void 0){super(),this.selectedChanged=!1,this.colorTransformChanged=!1,this._selected=!1,this._colorTransforms=[],this._colorTransformsMap=new Map,this._data=U||new B,this._bounds=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0)),this.recalculateBounds=()=>{this._bounds=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0));for(let F=0;F<this._data.vertexCount;F++)this._bounds.expand(new t(this._data.positions[3*F],this._data.positions[3*F+1],this._data.positions[3*F+2]))},this.applyPosition=()=>{this.data.translate(this.position),this.position=new t},this.applyRotation=()=>{this.data.rotate(this.rotation),this.rotation=new F},this.applyScale=()=>{this.data.scale(this.scale),this.scale=new t(1,1,1)},this.recalculateBounds()}saveToFile(t=null,F="splat"){if(!document)return;if(!t){const U=new Date;t=`splat-${U.getFullYear()}-${U.getMonth()+1}-${U.getDate()}.${F}`}const U=this.clone();U.applyRotation(),U.applyScale(),U.applyPosition();const l=U.data.serialize();let n;if("ply"===F){const t=i.SplatToPLY(l.buffer,U.data.vertexCount);n=new Blob([t],{type:"application/octet-stream"})}else n=new Blob([l.buffer],{type:"application/octet-stream"});const Q=document.createElement("a");Q.download=t,Q.href=URL.createObjectURL(n),Q.click()}get data(){return this._data}get selected(){return this._selected}set selected(t){this._selected!==t&&(this._selected=t,this.selectedChanged=!0,this.dispatchEvent(this._changeEvent))}get colorTransforms(){return this._colorTransforms}get colorTransformsMap(){return this._colorTransformsMap}get bounds(){let t=this._bounds.center();t=t.add(this.position);let F=this._bounds.size();return F=F.multiply(this.scale),new V(t.subtract(F.divide(2)),t.add(F.divide(2)))}clone(){const t=new Z(this.data.clone());return t.position=this.position.clone(),t.rotation=this.rotation.clone(),t.scale=this.scale.clone(),t}}class R extends d{constructor(t){super(),this._data=t}get data(){return this._data}}class c{constructor(){this._fx=1132,this._fy=1132,this._near=.1,this._far=100,this._width=512,this._height=512,this._projectionMatrix=new l,this._viewMatrix=new l,this._viewProj=new l,this._updateProjectionMatrix=()=>{this._projectionMatrix=new l(2*this.fx/this.width,0,0,0,0,-2*this.fy/this.height,0,0,0,0,this.far/(this.far-this.near),1,0,0,-this.far*this.near/(this.far-this.near),0),this._viewProj=this.projectionMatrix.multiply(this.viewMatrix)},this.update=(t,F)=>{const U=A.RotationFromQuaternion(F).buffer,n=t.flat();this._viewMatrix=new l(U[0],U[1],U[2],0,U[3],U[4],U[5],0,U[6],U[7],U[8],0,-n[0]*U[0]-n[1]*U[3]-n[2]*U[6],-n[0]*U[1]-n[1]*U[4]-n[2]*U[7],-n[0]*U[2]-n[1]*U[5]-n[2]*U[8],1),this._viewProj=this.projectionMatrix.multiply(this.viewMatrix)},this.setSize=(t,F)=>{this._width=t,this._height=F,this._updateProjectionMatrix()}}get fx(){return this._fx}set fx(t){this._fx!==t&&(this._fx=t,this._updateProjectionMatrix())}get fy(){return this._fy}set fy(t){this._fy!==t&&(this._fy=t,this._updateProjectionMatrix())}get near(){return this._near}set near(t){this._near!==t&&(this._near=t,this._updateProjectionMatrix())}get far(){return this._far}set far(t){this._far!==t&&(this._far=t,this._updateProjectionMatrix())}get width(){return this._width}get height(){return this._height}get projectionMatrix(){return this._projectionMatrix}get viewMatrix(){return this._viewMatrix}get viewProj(){return this._viewProj}}class s{constructor(t=0,F=0,U=0,l=0){this.x=t,this.y=F,this.z=U,this.w=l}equals(t){return this.x===t.x&&(this.y===t.y&&(this.z===t.z&&this.w===t.w))}add(t){return"number"==typeof t?new s(this.x+t,this.y+t,this.z+t,this.w+t):new s(this.x+t.x,this.y+t.y,this.z+t.z,this.w+t.w)}subtract(t){return"number"==typeof t?new s(this.x-t,this.y-t,this.z-t,this.w-t):new s(this.x-t.x,this.y-t.y,this.z-t.z,this.w-t.w)}multiply(t){return"number"==typeof t?new s(this.x*t,this.y*t,this.z*t,this.w*t):t instanceof s?new s(this.x*t.x,this.y*t.y,this.z*t.z,this.w*t.w):new s(this.x*t.buffer[0]+this.y*t.buffer[4]+this.z*t.buffer[8]+this.w*t.buffer[12],this.x*t.buffer[1]+this.y*t.buffer[5]+this.z*t.buffer[9]+this.w*t.buffer[13],this.x*t.buffer[2]+this.y*t.buffer[6]+this.z*t.buffer[10]+this.w*t.buffer[14],this.x*t.buffer[3]+this.y*t.buffer[7]+this.z*t.buffer[11]+this.w*t.buffer[15])}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z+this.w*t.w}lerp(t,F){return new s(this.x+(t.x-this.x)*F,this.y+(t.y-this.y)*F,this.z+(t.z-this.z)*F,this.w+(t.w-this.w)*F)}magnitude(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}distanceTo(t){return Math.sqrt((this.x-t.x)**2+(this.y-t.y)**2+(this.z-t.z)**2+(this.w-t.w)**2)}normalize(){const t=this.magnitude();return new s(this.x/t,this.y/t,this.z/t,this.w/t)}flat(){return[this.x,this.y,this.z,this.w]}clone(){return new s(this.x,this.y,this.z,this.w)}toString(){return`[${this.flat().join(", ")}]`}}class o extends d{constructor(F,U){super(),this._data=F||new c,this._position=U||new t(1,1,5),this.update=()=>{this.data.update(this.position,this.rotation)},this.screenPointToRay=(F,U)=>{const l=new s(F,U,-1,1),n=this._data.projectionMatrix.invert(),Q=l.multiply(n),e=this._data.viewMatrix.invert(),d=Q.multiply(e);return new t(d.x/d.w,d.y/d.w,d.z/d.w).subtract(this.position).normalize()}}get data(){return this._data}}class r extends U{constructor(){super(),this._objects=[],this.addObject=t=>{this.objects.push(t),this.dispatchEvent(new n(t))},this.removeObject=t=>{const F=this.objects.indexOf(t);if(F<0)throw new Error("Object not found in scene");this.objects.splice(F,1),this.dispatchEvent(new Q(t))},this.findObject=t=>{for(const F of this.objects)if(t(F))return F},this.findObjectOfType=t=>{for(const F of this.objects)if(F instanceof t)return F},this.reset=()=>{const t=this.objects.slice();for(const F of t)this.removeObject(F)},this.reset()}getMergedSceneDataBuffer(t="splat"){const F=[];let U=0;for(const t of this.objects)if(t instanceof Z){const l=t.clone();l.applyRotation(),l.applyScale(),l.applyPosition();const n=l.data.serialize();F.push(n),U+=l.data.vertexCount}const l=new Uint8Array(U*B.RowLength);let n=0;for(const t of F)l.set(t,n),n+=t.length;return"ply"===t?i.SplatToPLY(l.buffer,U):l.buffer}saveToFile(t=null,F="splat"){if(!document)return;if(!t){const U=new Date;t=`scene-${U.getFullYear()}-${U.getMonth()+1}-${U.getDate()}.${F}`}const U=this.getMergedSceneDataBuffer(F),l=new Blob([U],{type:"application/octet-stream"}),n=document.createElement("a");n.download=t,n.href=URL.createObjectURL(l),n.click()}get objects(){return this._objects}}async function h(t,F){const U=await fetch(t,{mode:"cors",credentials:"omit",cache:F?"force-cache":"default"});if(200!=U.status)throw new Error(U.status+" Unable to load "+U.url);return U}async function W(t,F){return t.headers.has("content-length")?async function(t,F){const U=t.body.getReader(),l=parseInt(t.headers.get("content-length")),n=new Uint8Array(l);let Q=0;for(;;){const{done:t,value:e}=await U.read();if(t)break;n.set(e,Q),Q+=e.length,null==F||F(Q/l)}return n}(t,F):async function(t,F){const U=t.body.getReader(),l=[];let n=0;for(;;){const{done:t,value:F}=await U.read();if(t)break;l.push(F),n+=F.length}const Q=new Uint8Array(n);let e=0;for(const t of l)Q.set(t,e),e+=t.length,null==F||F(e/n);return Q}(t,F)}class I{static async LoadAsync(t,F,U,l=!1){const n=await h(t,l),Q=await W(n,U);return this.LoadFromArrayBuffer(Q,F)}static async LoadFromFileAsync(t,F,U){const l=new FileReader;let n=new Z;return l.onload=t=>{n=this.LoadFromArrayBuffer(t.target.result,F)},l.onprogress=t=>{null==U||U(t.loaded/t.total)},l.readAsArrayBuffer(t),await new Promise((t=>{l.onloadend=()=>{t()}})),n}static LoadFromArrayBuffer(t,F){const U=new Uint8Array(t),l=B.Deserialize(U),n=new Z(l);return F.addObject(n),n}}class m{static async LoadAsync(t,F,U,l="",n=!1){const Q=await h(t,n),e=await W(Q,U);if(112!==e[0]||108!==e[1]||121!==e[2]||10!==e[3])throw new Error("Invalid PLY file");return this.LoadFromArrayBuffer(e.buffer,F,l)}static async LoadFromFileAsync(t,F,U,l=""){const n=new FileReader;let Q=new Z;return n.onload=t=>{Q=this.LoadFromArrayBuffer(t.target.result,F,l)},n.onprogress=t=>{null==U||U(t.loaded/t.total)},n.readAsArrayBuffer(t),await new Promise((t=>{n.onloadend=()=>{t()}})),Q}static LoadFromArrayBuffer(t,F,U=""){const l=new Uint8Array(this._ParsePLYBuffer(t,U)),n=B.Deserialize(l),Q=new Z(n);return F.addObject(Q),Q}static _ParsePLYBuffer(U,l){const n=new Uint8Array(U),Q=(new TextDecoder).decode(n.slice(0,10240)),e="end_header\n",d=Q.indexOf(e);if(d<0)throw new Error("Unable to read .ply file header");const A=parseInt(/element vertex (\d+)\n/.exec(Q)[1]);let a=0;const V={double:8,int:4,uint:4,float:4,short:2,ushort:2,uchar:1},Z=[];for(const t of Q.slice(0,d).split("\n").filter((t=>t.startsWith("property ")))){const[F,U,l]=t.split(" ");if(Z.push({name:l,type:U,offset:a}),!V[U])throw new Error(`Unsupported property type: ${U}`);a+=V[U]}const R=new DataView(U,d+11),c=new ArrayBuffer(B.RowLength*A),s=F.FromEuler(new t(Math.PI/2,0,0));for(let t=0;t<A;t++){const U=new Float32Array(c,t*B.RowLength,3),n=new Float32Array(c,t*B.RowLength+12,3),Q=new Uint8ClampedArray(c,t*B.RowLength+24,4),e=new Uint8ClampedArray(c,t*B.RowLength+28,4);let d=255,A=0,V=0,o=0;Z.forEach((F=>{let l;switch(F.type){case"float":l=R.getFloat32(F.offset+t*a,!0);break;case"int":l=R.getInt32(F.offset+t*a,!0);break;default:throw new Error(`Unsupported property type: ${F.type}`)}switch(F.name){case"x":U[0]=l;break;case"y":U[1]=l;break;case"z":U[2]=l;break;case"scale_0":case"scaling_0":n[0]=Math.exp(l);break;case"scale_1":case"scaling_1":n[1]=Math.exp(l);break;case"scale_2":case"scaling_2":n[2]=Math.exp(l);break;case"red":Q[0]=l;break;case"green":Q[1]=l;break;case"blue":Q[2]=l;break;case"f_dc_0":case"features_0":Q[0]=255*(.5+i.SH_C0*l);break;case"f_dc_1":case"features_1":Q[1]=255*(.5+i.SH_C0*l);break;case"f_dc_2":case"features_2":Q[2]=255*(.5+i.SH_C0*l);break;case"f_dc_3":Q[3]=255*(.5+i.SH_C0*l);break;case"opacity":case"opacity_0":Q[3]=1/(1+Math.exp(-l))*255;break;case"rot_0":case"rotation_0":d=l;break;case"rot_1":case"rotation_1":A=l;break;case"rot_2":case"rotation_2":V=l;break;case"rot_3":case"rotation_3":o=l}}));let r=new F(A,V,o,d);switch(l){case"polycam":{const t=U[1];U[1]=-U[2],U[2]=t,r=s.multiply(r);break}case"":break;default:throw new Error(`Unsupported format: ${l}`)}r=r.normalize(),e[0]=128*r.w+128,e[1]=128*r.x+128,e[2]=128*r.y+128,e[3]=128*r.z+128}return c}}class b{static async LoadAsync(t,F,U,l,n=!1){const Q=await h(t,n),e=await W(Q,l);return this._ParseSplatvBuffer(e.buffer,F,U)}static async LoadFromFileAsync(t,F,U,l){const n=new FileReader;let Q=null;if(n.onload=t=>{Q=this._ParseSplatvBuffer(t.target.result,F,U)},n.onprogress=t=>{null==l||l(t.loaded/t.total)},n.readAsArrayBuffer(t),await new Promise((t=>{n.onloadend=()=>{t()}})),!Q)throw new Error("Failed to load splatv file");return Q}static _ParseSplatvBuffer(U,l,n){let Q=null;const e=(U,e,d)=>{if("magic"===U.type){const t=new Int32Array(e.buffer);if(26443!==t[0])throw new Error("Invalid splatv file");d.push({size:t[1],type:"chunks"})}else if("chunks"===U.type){const U=JSON.parse(new TextDecoder("utf-8").decode(e));if(0==U.length)throw new Error("Invalid splatv file");U.length>1&&console.warn("Splatv file contains more than one chunk, only the first one will be loaded");const l=U[0],Q=l.cameras;if(n&&Q&&Q.length){const U=Q[0],l=new t(U.position[0],U.position[1],U.position[2]),e=F.FromMatrix3(new A(U.rotation[0][0],U.rotation[0][1],U.rotation[0][2],U.rotation[1][0],U.rotation[1][1],U.rotation[1][2],U.rotation[2][0],U.rotation[2][1],U.rotation[2][2]));n.position=l,n.rotation=e}d.push(l)}else if("splat"===U.type){const t=a.Deserialize(e,U.texwidth,U.texheight),F=new R(t);l.addObject(F),Q=F}},d=new Uint8Array(U),B=[{size:8,type:"magic",texwidth:0,texheight:0}];let i=B.shift(),V=new Uint8Array(i.size),Z=0,c=0;for(;i;){for(;Z<i.size;){const t=Math.min(i.size-Z,d.length-c);V.set(d.subarray(c,c+t),Z),Z+=t,c+=t}if(e(i,V,B),Q)return Q;i=B.shift(),i&&(V=new Uint8Array(i.size),Z=0)}throw new Error("Invalid splatv file")}}function J(t,F,U){var l=void 0===F?null:F,n=function(t,F){var U=atob(t);if(F){for(var l=new Uint8Array(U.length),n=0,Q=U.length;n<Q;++n)l[n]=U.charCodeAt(n);return String.fromCharCode.apply(null,new Uint16Array(l.buffer))}return U}(t,void 0!==U&&U),Q=n.indexOf("\n",10)+1,e=n.substring(Q)+(l?"//# sourceMappingURL="+l:""),d=new Blob([e],{type:"application/javascript"});return URL.createObjectURL(d)}function g(t,F,U){var l;return function(n){return l=l||J(t,F,U),new Worker(l,n)}}var C=g("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIGxvYWRXYXNtID0gKCgpID0+IHsNCiAgICANCiAgICByZXR1cm4gKA0KICBhc3luYyBmdW5jdGlvbihtb2R1bGVBcmcgPSB7fSkgew0KICAgIHZhciBtb2R1bGVSdG47DQoNCiAgdmFyIE1vZHVsZT1tb2R1bGVBcmc7dmFyIHJlYWR5UHJvbWlzZVJlc29sdmUscmVhZHlQcm9taXNlUmVqZWN0O3ZhciByZWFkeVByb21pc2U9bmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e3JlYWR5UHJvbWlzZVJlc29sdmU9cmVzb2x2ZTtyZWFkeVByb21pc2VSZWplY3Q9cmVqZWN0O30pO3ZhciBtb2R1bGVPdmVycmlkZXM9T2JqZWN0LmFzc2lnbih7fSxNb2R1bGUpO3ZhciBzY3JpcHREaXJlY3Rvcnk9IiI7dmFyIHJlYWRCaW5hcnk7e3tzY3JpcHREaXJlY3Rvcnk9c2VsZi5sb2NhdGlvbi5ocmVmO31pZihzY3JpcHREaXJlY3Rvcnkuc3RhcnRzV2l0aCgiYmxvYjoiKSl7c2NyaXB0RGlyZWN0b3J5PSIiO31lbHNlIHtzY3JpcHREaXJlY3Rvcnk9c2NyaXB0RGlyZWN0b3J5LnNsaWNlKDAsc2NyaXB0RGlyZWN0b3J5LnJlcGxhY2UoL1s/I10uKi8sIiIpLmxhc3RJbmRleE9mKCIvIikrMSk7fXt7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX07fX19TW9kdWxlWyJwcmludCJdfHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9TW9kdWxlWyJwcmludEVyciJdfHxjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7T2JqZWN0LmFzc2lnbihNb2R1bGUsbW9kdWxlT3ZlcnJpZGVzKTttb2R1bGVPdmVycmlkZXM9bnVsbDtpZihNb2R1bGVbImFyZ3VtZW50cyJdKU1vZHVsZVsiYXJndW1lbnRzIl07aWYoTW9kdWxlWyJ0aGlzUHJvZ3JhbSJdKU1vZHVsZVsidGhpc1Byb2dyYW0iXTt2YXIgd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTt2YXIgd2FzbU1lbW9yeTt2YXIgQUJPUlQ9ZmFsc2U7dmFyIEhFQVA4LEhFQVBVOCxIRUFQMTYsSEVBUFUxNixIRUFQMzIsSEVBUFUzMixIRUFQRjMyLEhFQVA2NCxIRUFQVTY0LEhFQVBGNjQ7ZnVuY3Rpb24gdXBkYXRlTWVtb3J5Vmlld3MoKXt2YXIgYj13YXNtTWVtb3J5LmJ1ZmZlcjtNb2R1bGVbIkhFQVA4Il09SEVBUDg9bmV3IEludDhBcnJheShiKTtNb2R1bGVbIkhFQVAxNiJdPUhFQVAxNj1uZXcgSW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVBVOCJdPUhFQVBVOD1uZXcgVWludDhBcnJheShiKTtNb2R1bGVbIkhFQVBVMTYiXT1IRUFQVTE2PW5ldyBVaW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVAzMiJdPUhFQVAzMj1uZXcgSW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBVMzIiXT1IRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBGMzIiXT1IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7TW9kdWxlWyJIRUFQRjY0Il09SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUDY0Il09SEVBUDY0PW5ldyBCaWdJbnQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUFU2NCJdPUhFQVBVNjQ9bmV3IEJpZ1VpbnQ2NEFycmF5KGIpO31mdW5jdGlvbiBwcmVSdW4oKXtpZihNb2R1bGVbInByZVJ1biJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZVJ1biJdPVtNb2R1bGVbInByZVJ1biJdXTt3aGlsZShNb2R1bGVbInByZVJ1biJdLmxlbmd0aCl7YWRkT25QcmVSdW4oTW9kdWxlWyJwcmVSdW4iXS5zaGlmdCgpKTt9fWNhbGxSdW50aW1lQ2FsbGJhY2tzKG9uUHJlUnVucyk7fWZ1bmN0aW9uIGluaXRSdW50aW1lKCl7d2FzbUV4cG9ydHNbIm0iXSgpO31mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpO319Y2FsbFJ1bnRpbWVDYWxsYmFja3Mob25Qb3N0UnVucyk7fXZhciBydW5EZXBlbmRlbmNpZXM9MDt2YXIgZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7ZnVuY3Rpb24gYWRkUnVuRGVwZW5kZW5jeShpZCl7cnVuRGVwZW5kZW5jaWVzKys7TW9kdWxlWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0/LihydW5EZXBlbmRlbmNpZXMpO31mdW5jdGlvbiByZW1vdmVSdW5EZXBlbmRlbmN5KGlkKXtydW5EZXBlbmRlbmNpZXMtLTtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXT8uKHJ1bkRlcGVuZGVuY2llcyk7aWYocnVuRGVwZW5kZW5jaWVzPT0wKXtpZihkZXBlbmRlbmNpZXNGdWxmaWxsZWQpe3ZhciBjYWxsYmFjaz1kZXBlbmRlbmNpZXNGdWxmaWxsZWQ7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7Y2FsbGJhY2soKTt9fX1mdW5jdGlvbiBhYm9ydCh3aGF0KXtNb2R1bGVbIm9uQWJvcnQiXT8uKHdoYXQpO3doYXQ9IkFib3J0ZWQoIit3aGF0KyIpIjtlcnIod2hhdCk7QUJPUlQ9dHJ1ZTt3aGF0Kz0iLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLiI7dmFyIGU9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcih3aGF0KTtyZWFkeVByb21pc2VSZWplY3QoZSk7dGhyb3cgZX12YXIgd2FzbUJpbmFyeUZpbGU9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCxBR0Z6YlFFQUFBQUJTd3RnQkg5L2YzOEFZQU4vZjM4QVlBVi9mMzkvZndCZ0JuOS9mMzkvZndCZ0FYOEFZQUYvQVg5Z0FBQmdBMzkvZndGL1lBSi9md0JnQlg5L2YzNStBR0FKZjM5L2YzOS9mMzkvQUFKREN3RmhBV0VBQVFGaEFXSUFBZ0ZoQVdNQUFRRmhBV1FBQVFGaEFXVUFDUUZoQVdZQUJBRmhBV2NBQ0FGaEFXZ0FBQUZoQVdrQUNBRmhBV29BQmdGaEFXc0FCUU1XRlFjRkJBWUVCQVlCQUFFRkJRTURBZ0lBQUFjSENnUUZBWEFCRUJBRkJ3RUJnZ0tBZ0FJR0NBRi9BVUhRblFRTEJ4a0dBV3dDQUFGdEFBNEJiZ0FmQVc4QUZnRndBQkFCY1FFQUNSVUJBRUVCQ3c4VkRROFBIZzBkRnhrY0RSZ2FHeEVNQVFJSzMwa1ZjUUVCZnlBQ1JRUkFJQUFvQWdRZ0FTZ0NCRVlQQ3lBQUlBRkdCRUJCQVE4TEFrQWdBQ2dDQkNJQ0xRQUFJZ0JGSUFBZ0FTZ0NCQ0lCTFFBQUlnTkhjZzBBQTBBZ0FTMEFBU0VESUFJdEFBRWlBRVVOQVNBQlFRRnFJUUVnQWtFQmFpRUNJQUFnQTBZTkFBc0xJQUFnQTBZTFR3RUNmMEhNR1NnQ0FDSUJJQUJCQjJwQmVIRWlBbW9oQUFKQUlBSkJBQ0FBSUFGTkcwVUVRQ0FBUHdCQkVIUk5EUUVnQUJBS0RRRUxRZEFaUVRBMkFnQkJmdzhMUWN3WklBQTJBZ0FnQVFzR0FDQUFFQkFMS1FCQnlCMUJEellDQUVITUhVRUFOZ0lBRUJGQnpCMUJ4QjBvQWdBMkFnQkJ4QjFCeUIwMkFnQUxBZ0FMM0FzQkNIOENRQ0FBUlEwQUlBQkJDR3NpQXlBQVFRUnJLQUlBSWdKQmVIRWlBR29oQlFKQUlBSkJBWEVOQUNBQ1FRSnhSUTBCSUFNZ0F5Z0NBQ0lFYXlJRFFlUVpLQUlBU1EwQklBQWdCR29oQUFKQUFrQUNRRUhvR1NnQ0FDQURSd1JBSUFNb0Fnd2hBU0FFUWY4QlRRUkFJQUVnQXlnQ0NDSUNSdzBDUWRRWlFkUVpLQUlBUVg0Z0JFRURkbmR4TmdJQURBVUxJQU1vQWhnaEJ5QUJJQU5IQkVBZ0F5Z0NDQ0lDSUFFMkFnd2dBU0FDTmdJSURBUUxJQU1vQWhRaUFnUi9JQU5CRkdvRklBTW9BaEFpQWtVTkF5QURRUkJxQ3lFRUEwQWdCQ0VHSUFJaUFVRVVhaUVFSUFFb0FoUWlBZzBBSUFGQkVHb2hCQ0FCS0FJUUlnSU5BQXNnQmtFQU5nSUFEQU1MSUFVb0FnUWlBa0VEY1VFRFJ3MERRZHdaSUFBMkFnQWdCU0FDUVg1eE5nSUVJQU1nQUVFQmNqWUNCQ0FGSUFBMkFnQVBDeUFDSUFFMkFnd2dBU0FDTmdJSURBSUxRUUFoQVFzZ0IwVU5BQUpBSUFNb0Fod2lCRUVDZEVHRUhHb2lBaWdDQUNBRFJnUkFJQUlnQVRZQ0FDQUJEUUZCMkJsQjJCa29BZ0JCZmlBRWQzRTJBZ0FNQWdzQ1FDQURJQWNvQWhCR0JFQWdCeUFCTmdJUURBRUxJQWNnQVRZQ0ZBc2dBVVVOQVFzZ0FTQUhOZ0lZSUFNb0FoQWlBZ1JBSUFFZ0FqWUNFQ0FDSUFFMkFoZ0xJQU1vQWhRaUFrVU5BQ0FCSUFJMkFoUWdBaUFCTmdJWUN5QURJQVZQRFFBZ0JTZ0NCQ0lFUVFGeFJRMEFBa0FDUUFKQUFrQWdCRUVDY1VVRVFFSHNHU2dDQUNBRlJnUkFRZXdaSUFNMkFnQkI0QmxCNEJrb0FnQWdBR29pQURZQ0FDQURJQUJCQVhJMkFnUWdBMEhvR1NnQ0FFY05Ca0hjR1VFQU5nSUFRZWdaUVFBMkFnQVBDMEhvR1NnQ0FDSUhJQVZHQkVCQjZCa2dBellDQUVIY0dVSGNHU2dDQUNBQWFpSUFOZ0lBSUFNZ0FFRUJjallDQkNBQUlBTnFJQUEyQWdBUEN5QUVRWGh4SUFCcUlRQWdCU2dDRENFQklBUkIvd0ZOQkVBZ0JTZ0NDQ0lDSUFGR0JFQkIxQmxCMUJrb0FnQkJmaUFFUVFOMmQzRTJBZ0FNQlFzZ0FpQUJOZ0lNSUFFZ0FqWUNDQXdFQ3lBRktBSVlJUWdnQVNBRlJ3UkFJQVVvQWdnaUFpQUJOZ0lNSUFFZ0FqWUNDQXdEQ3lBRktBSVVJZ0lFZnlBRlFSUnFCU0FGS0FJUUlnSkZEUUlnQlVFUWFnc2hCQU5BSUFRaEJpQUNJZ0ZCRkdvaEJDQUJLQUlVSWdJTkFDQUJRUkJxSVFRZ0FTZ0NFQ0lDRFFBTElBWkJBRFlDQUF3Q0N5QUZJQVJCZm5FMkFnUWdBeUFBUVFGeU5nSUVJQUFnQTJvZ0FEWUNBQXdEQzBFQUlRRUxJQWhGRFFBQ1FDQUZLQUljSWdSQkFuUkJoQnhxSWdJb0FnQWdCVVlFUUNBQ0lBRTJBZ0FnQVEwQlFkZ1pRZGdaS0FJQVFYNGdCSGR4TmdJQURBSUxBa0FnQlNBSUtBSVFSZ1JBSUFnZ0FUWUNFQXdCQ3lBSUlBRTJBaFFMSUFGRkRRRUxJQUVnQ0RZQ0dDQUZLQUlRSWdJRVFDQUJJQUkyQWhBZ0FpQUJOZ0lZQ3lBRktBSVVJZ0pGRFFBZ0FTQUNOZ0lVSUFJZ0FUWUNHQXNnQXlBQVFRRnlOZ0lFSUFBZ0Eyb2dBRFlDQUNBRElBZEhEUUJCM0JrZ0FEWUNBQThMSUFCQi93Rk5CRUFnQUVGNGNVSDhHV29oQWdKL1FkUVpLQUlBSWdSQkFTQUFRUU4yZENJQWNVVUVRRUhVR1NBQUlBUnlOZ0lBSUFJTUFRc2dBaWdDQ0FzaEFDQUNJQU0yQWdnZ0FDQUROZ0lNSUFNZ0FqWUNEQ0FESUFBMkFnZ1BDMEVmSVFFZ0FFSC8vLzhIVFFSQUlBQkJKaUFBUVFoMlp5SUNhM1pCQVhFZ0FrRUJkR3RCUG1vaEFRc2dBeUFCTmdJY0lBTkNBRGNDRUNBQlFRSjBRWVFjYWlFRUFuOENRQUovUWRnWktBSUFJZ1pCQVNBQmRDSUNjVVVFUUVIWUdTQUNJQVp5TmdJQUlBUWdBellDQUVFWUlRRkJDQXdCQ3lBQVFSa2dBVUVCZG10QkFDQUJRUjlIRzNRaEFTQUVLQUlBSVFRRFFDQUVJZ0lvQWdSQmVIRWdBRVlOQWlBQlFSMTJJUVFnQVVFQmRDRUJJQUlnQkVFRWNXb2lCaWdDRUNJRURRQUxJQVlnQXpZQ0VFRVlJUUVnQWlFRVFRZ0xJUUFnQXlJQ0RBRUxJQUlvQWdnaUJDQUROZ0lNSUFJZ0F6WUNDRUVZSVFCQkNDRUJRUUFMSVFZZ0FTQURhaUFFTmdJQUlBTWdBallDRENBQUlBTnFJQVkyQWdCQjlCbEI5QmtvQWdCQkFXc2lBRUYvSUFBYk5nSUFDd3ZhQXdCQnlCQkJ5Z29RQ0VIVUVFSDVDVUVCUVFBUUIwSGdFRUcwQ1VFQlFZQi9RZjhBRUFGQitCQkJyUWxCQVVHQWYwSC9BQkFCUWV3UVFhc0pRUUZCQUVIL0FSQUJRWVFSUWY4SVFRSkJnSUIrUWYvL0FSQUJRWkFSUWZZSVFRSkJBRUgvL3dNUUFVR2NFVUdPQ1VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCcUJGQmhRbEJCRUVBUVg4UUFVRzBFVUdIQ2tFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCd0JGQi9nbEJCRUVBUVg4UUFVSE1FVUdaQ1VFSVFvQ0FnSUNBZ0lDQWdIOUMvLy8vLy8vLy8vLy9BQkFFUWRnUlFaZ0pRUWhDQUVKL0VBUkI1QkZCa2dsQkJCQURRZkFSUWNNS1FRZ1FBMEdBRTBHWkNoQUdRY2dUUVFSQmpBb1FBa0dRRkVFQ1FhVUtFQUpCM0JSQkJFRzBDaEFDUWFnVkVBVkJ4QlZCQUVHbURoQUFRZXdWUVFCQjZ3NFFBRUdVRmtFQlFjUU9FQUJCdkJaQkFrSHpDaEFBUWVRV1FRTkJrZ3NRQUVHTUYwRUVRYm9MRUFCQnRCZEJCVUhYQ3hBQVFkd1hRUVJCa0E4UUFFR0VHRUVGUWE0UEVBQkI3QlZCQUVHOURCQUFRWlFXUVFGQm5Bd1FBRUc4RmtFQ1FmOE1FQUJCNUJaQkEwSGREQkFBUVl3WFFRUkJoUTRRQUVHMEYwRUZRZU1ORUFCQnJCaEJDRUhDRFJBQVFkUVlRUWxCb0EwUUFFSDhHRUVHUWYwTEVBQkJwQmxCQjBIVkR4QUFDeUFBQWtBZ0FTQUFLQUlFUncwQUlBQW9BaHhCQVVZTkFDQUFJQUkyQWh3TEM1b0JBQ0FBUVFFNkFEVUNRQ0FDSUFBb0FnUkhEUUFnQUVFQk9nQTBBa0FnQUNnQ0VDSUNSUVJBSUFCQkFUWUNKQ0FBSUFNMkFoZ2dBQ0FCTmdJUUlBTkJBVWNOQWlBQUtBSXdRUUZHRFFFTUFnc2dBU0FDUmdSQUlBQW9BaGdpQWtFQ1JnUkFJQUFnQXpZQ0dDQURJUUlMSUFBb0FqQkJBVWNOQWlBQ1FRRkdEUUVNQWdzZ0FDQUFLQUlrUVFGcU5nSWtDeUFBUVFFNkFEWUxDM1lCQVg4Z0FDZ0NKQ0lEUlFSQUlBQWdBallDR0NBQUlBRTJBaEFnQUVFQk5nSWtJQUFnQUNnQ09EWUNGQThMQWtBQ1FDQUFLQUlVSUFBb0FqaEhEUUFnQUNnQ0VDQUJSdzBBSUFBb0FoaEJBa2NOQVNBQUlBSTJBaGdQQ3lBQVFRRTZBRFlnQUVFQ05nSVlJQUFnQTBFQmFqWUNKQXNMQkFBZ0FBdlJKd0VMZnlNQVFSQnJJZ29rQUFKQUFrQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUlBQkI5QUZOQkVCQjFCa29BZ0FpQkVFUUlBQkJDMnBCK0FOeElBQkJDMGtiSWdaQkEzWWlBSFlpQVVFRGNRUkFBa0FnQVVGL2MwRUJjU0FBYWlJQ1FRTjBJZ0ZCL0JscUlnQWdBVUdFR21vb0FnQWlBU2dDQ0NJRlJnUkFRZFFaSUFSQmZpQUNkM0UyQWdBTUFRc2dCU0FBTmdJTUlBQWdCVFlDQ0FzZ0FVRUlhaUVBSUFFZ0FrRURkQ0lDUVFOeU5nSUVJQUVnQW1vaUFTQUJLQUlFUVFGeU5nSUVEQXNMSUFaQjNCa29BZ0FpQ0UwTkFTQUJCRUFDUUVFQ0lBQjBJZ0pCQUNBQ2EzSWdBU0FBZEhGb0lnRkJBM1FpQUVIOEdXb2lBaUFBUVlRYWFpZ0NBQ0lBS0FJSUlnVkdCRUJCMUJrZ0JFRitJQUYzY1NJRU5nSUFEQUVMSUFVZ0FqWUNEQ0FDSUFVMkFnZ0xJQUFnQmtFRGNqWUNCQ0FBSUFacUlnY2dBVUVEZENJQklBWnJJZ1ZCQVhJMkFnUWdBQ0FCYWlBRk5nSUFJQWdFUUNBSVFYaHhRZndaYWlFQlFlZ1pLQUlBSVFJQ2Z5QUVRUUVnQ0VFRGRuUWlBM0ZGQkVCQjFCa2dBeUFFY2pZQ0FDQUJEQUVMSUFFb0FnZ0xJUU1nQVNBQ05nSUlJQU1nQWpZQ0RDQUNJQUUyQWd3Z0FpQUROZ0lJQ3lBQVFRaHFJUUJCNkJrZ0J6WUNBRUhjR1NBRk5nSUFEQXNMUWRnWktBSUFJZ3RGRFFFZ0MyaEJBblJCaEJ4cUtBSUFJZ0lvQWdSQmVIRWdCbXNoQXlBQ0lRRURRQUpBSUFFb0FoQWlBRVVFUUNBQktBSVVJZ0JGRFFFTElBQW9BZ1JCZUhFZ0Jtc2lBU0FESUFFZ0Ewa2lBUnNoQXlBQUlBSWdBUnNoQWlBQUlRRU1BUXNMSUFJb0FoZ2hDU0FDSUFJb0Fnd2lBRWNFUUNBQ0tBSUlJZ0VnQURZQ0RDQUFJQUUyQWdnTUNnc2dBaWdDRkNJQkJIOGdBa0VVYWdVZ0FpZ0NFQ0lCUlEwRElBSkJFR29MSVFVRFFDQUZJUWNnQVNJQVFSUnFJUVVnQUNnQ0ZDSUJEUUFnQUVFUWFpRUZJQUFvQWhBaUFRMEFDeUFIUVFBMkFnQU1DUXRCZnlFR0lBQkJ2MzlMRFFBZ0FFRUxhaUlCUVhoeElRWkIyQmtvQWdBaUIwVU5BRUVmSVFoQkFDQUdheUVESUFCQjlQLy9CMDBFUUNBR1FTWWdBVUVJZG1jaUFHdDJRUUZ4SUFCQkFYUnJRVDVxSVFnTEFrQUNRQUpBSUFoQkFuUkJoQnhxS0FJQUlnRkZCRUJCQUNFQURBRUxRUUFoQUNBR1FSa2dDRUVCZG10QkFDQUlRUjlIRzNRaEFnTkFBa0FnQVNnQ0JFRjRjU0FHYXlJRUlBTlBEUUFnQVNFRklBUWlBdzBBUVFBaEF5QUJJUUFNQXdzZ0FDQUJLQUlVSWdRZ0JDQUJJQUpCSFhaQkJIRnFLQUlRSWdGR0d5QUFJQVFiSVFBZ0FrRUJkQ0VDSUFFTkFBc0xJQUFnQlhKRkJFQkJBQ0VGUVFJZ0NIUWlBRUVBSUFCcmNpQUhjU0lBUlEwRElBQm9RUUowUVlRY2FpZ0NBQ0VBQ3lBQVJRMEJDd05BSUFBb0FnUkJlSEVnQm1zaUFpQURTU0VCSUFJZ0F5QUJHeUVESUFBZ0JTQUJHeUVGSUFBb0FoQWlBUVIvSUFFRklBQW9BaFFMSWdBTkFBc0xJQVZGRFFBZ0EwSGNHU2dDQUNBR2EwOE5BQ0FGS0FJWUlRZ2dCU0FGS0FJTUlnQkhCRUFnQlNnQ0NDSUJJQUEyQWd3Z0FDQUJOZ0lJREFnTElBVW9BaFFpQVFSL0lBVkJGR29GSUFVb0FoQWlBVVVOQXlBRlFSQnFDeUVDQTBBZ0FpRUVJQUVpQUVFVWFpRUNJQUFvQWhRaUFRMEFJQUJCRUdvaEFpQUFLQUlRSWdFTkFBc2dCRUVBTmdJQURBY0xJQVpCM0Jrb0FnQWlCVTBFUUVIb0dTZ0NBQ0VBQWtBZ0JTQUdheUlCUVJCUEJFQWdBQ0FHYWlJQ0lBRkJBWEkyQWdRZ0FDQUZhaUFCTmdJQUlBQWdCa0VEY2pZQ0JBd0JDeUFBSUFWQkEzSTJBZ1FnQUNBRmFpSUJJQUVvQWdSQkFYSTJBZ1JCQUNFQ1FRQWhBUXRCM0JrZ0FUWUNBRUhvR1NBQ05nSUFJQUJCQ0dvaEFBd0pDeUFHUWVBWktBSUFJZ0pKQkVCQjRCa2dBaUFHYXlJQk5nSUFRZXdaUWV3WktBSUFJZ0FnQm1vaUFqWUNBQ0FDSUFGQkFYSTJBZ1FnQUNBR1FRTnlOZ0lFSUFCQkNHb2hBQXdKQzBFQUlRQWdCa0V2YWlJREFuOUJyQjBvQWdBRVFFRzBIU2dDQUF3QkMwRzRIVUovTndJQVFiQWRRb0NnZ0lDQWdBUTNBZ0JCckIwZ0NrRU1ha0Z3Y1VIWXF0V3FCWE0yQWdCQndCMUJBRFlDQUVHUUhVRUFOZ0lBUVlBZ0N5SUJhaUlFUVFBZ0FXc2lCM0VpQVNBR1RRMElRWXdkS0FJQUlnVUVRRUdFSFNnQ0FDSUlJQUZxSWdrZ0NFMGdCU0FKU1hJTkNRc0NRRUdRSFMwQUFFRUVjVVVFUUFKQUFrQUNRQUpBUWV3WktBSUFJZ1VFUUVHVUhTRUFBMEFnQUNnQ0FDSUlJQVZOQkVBZ0JTQUlJQUFvQWdScVNRMERDeUFBS0FJSUlnQU5BQXNMUVFBUURDSUNRWDlHRFFNZ0FTRUVRYkFkS0FJQUlnQkJBV3NpQlNBQ2NRUkFJQUVnQW1zZ0FpQUZha0VBSUFCcmNXb2hCQXNnQkNBR1RRMERRWXdkS0FJQUlnQUVRRUdFSFNnQ0FDSUZJQVJxSWdjZ0JVMGdBQ0FIU1hJTkJBc2dCQkFNSWdBZ0FrY05BUXdGQ3lBRUlBSnJJQWR4SWdRUURDSUNJQUFvQWdBZ0FDZ0NCR3BHRFFFZ0FpRUFDeUFBUVg5R0RRRWdCa0V3YWlBRVRRUkFJQUFoQWd3RUMwRzBIU2dDQUNJQ0lBTWdCR3RxUVFBZ0FtdHhJZ0lRREVGL1JnMEJJQUlnQkdvaEJDQUFJUUlNQXdzZ0FrRi9SdzBDQzBHUUhVR1FIU2dDQUVFRWNqWUNBQXNnQVJBTUlnSkJmMFpCQUJBTUlnQkJmMFp5SUFBZ0FrMXlEUVVnQUNBQ2F5SUVJQVpCS0dwTkRRVUxRWVFkUVlRZEtBSUFJQVJxSWdBMkFnQkJpQjBvQWdBZ0FFa0VRRUdJSFNBQU5nSUFDd0pBUWV3WktBSUFJZ01FUUVHVUhTRUFBMEFnQWlBQUtBSUFJZ0VnQUNnQ0JDSUZha1lOQWlBQUtBSUlJZ0FOQUFzTUJBdEI1QmtvQWdBaUFFRUFJQUFnQWswYlJRUkFRZVFaSUFJMkFnQUxRUUFoQUVHWUhTQUVOZ0lBUVpRZElBSTJBZ0JCOUJsQmZ6WUNBRUg0R1VHc0hTZ0NBRFlDQUVHZ0hVRUFOZ0lBQTBBZ0FFRURkQ0lCUVlRYWFpQUJRZndaYWlJRk5nSUFJQUZCaUJwcUlBVTJBZ0FnQUVFQmFpSUFRU0JIRFFBTFFlQVpJQVJCS0dzaUFFRjRJQUpyUVFkeElnRnJJZ1UyQWdCQjdCa2dBU0FDYWlJQk5nSUFJQUVnQlVFQmNqWUNCQ0FBSUFKcVFTZzJBZ1JCOEJsQnZCMG9BZ0EyQWdBTUJBc2dBaUFEVFNBQklBTkxjZzBDSUFBb0FneEJDSEVOQWlBQUlBUWdCV28yQWdSQjdCa2dBMEY0SUFOclFRZHhJZ0JxSWdFMkFnQkI0QmxCNEJrb0FnQWdCR29pQWlBQWF5SUFOZ0lBSUFFZ0FFRUJjallDQkNBQ0lBTnFRU2cyQWdSQjhCbEJ2QjBvQWdBMkFnQU1Bd3RCQUNFQURBWUxRUUFoQUF3RUMwSGtHU2dDQUNBQ1N3UkFRZVFaSUFJMkFnQUxJQUlnQkdvaEJVR1VIU0VBQWtBRFFDQUZJQUFvQWdBaUFVY0VRQ0FBS0FJSUlnQU5BUXdDQ3dzZ0FDMEFERUVJY1VVTkF3dEJsQjBoQUFOQUFrQWdBQ2dDQUNJQklBTk5CRUFnQXlBQklBQW9BZ1JxSWdWSkRRRUxJQUFvQWdnaEFBd0JDd3RCNEJrZ0JFRW9heUlBUVhnZ0FtdEJCM0VpQVdzaUJ6WUNBRUhzR1NBQklBSnFJZ0UyQWdBZ0FTQUhRUUZ5TmdJRUlBQWdBbXBCS0RZQ0JFSHdHVUc4SFNnQ0FEWUNBQ0FESUFWQkp5QUZhMEVIY1dwQkwyc2lBQ0FBSUFOQkVHcEpHeUlCUVJzMkFnUWdBVUdjSFNrQ0FEY0NFQ0FCUVpRZEtRSUFOd0lJUVp3ZElBRkJDR28yQWdCQm1CMGdCRFlDQUVHVUhTQUNOZ0lBUWFBZFFRQTJBZ0FnQVVFWWFpRUFBMEFnQUVFSE5nSUVJQUJCQ0dvZ0FFRUVhaUVBSUFWSkRRQUxJQUVnQTBZTkFDQUJJQUVvQWdSQmZuRTJBZ1FnQXlBQklBTnJJZ0pCQVhJMkFnUWdBU0FDTmdJQUFuOGdBa0gvQVUwRVFDQUNRWGh4UWZ3WmFpRUFBbjlCMUJrb0FnQWlBVUVCSUFKQkEzWjBJZ0p4UlFSQVFkUVpJQUVnQW5JMkFnQWdBQXdCQ3lBQUtBSUlDeUVCSUFBZ0F6WUNDQ0FCSUFNMkFneEJEQ0VDUVFnTUFRdEJIeUVBSUFKQi8vLy9CMDBFUUNBQ1FTWWdBa0VJZG1jaUFHdDJRUUZ4SUFCQkFYUnJRVDVxSVFBTElBTWdBRFlDSENBRFFnQTNBaEFnQUVFQ2RFR0VIR29oQVFKQUFrQkIyQmtvQWdBaUJVRUJJQUIwSWdSeFJRUkFRZGdaSUFRZ0JYSTJBZ0FnQVNBRE5nSUFEQUVMSUFKQkdTQUFRUUYyYTBFQUlBQkJIMGNiZENFQUlBRW9BZ0FoQlFOQUlBVWlBU2dDQkVGNGNTQUNSZzBDSUFCQkhYWWhCU0FBUVFGMElRQWdBU0FGUVFSeGFpSUVLQUlRSWdVTkFBc2dCQ0FETmdJUUN5QURJQUUyQWhoQkNDRUNJQU1pQVNFQVFRd01BUXNnQVNnQ0NDSUFJQU0yQWd3Z0FTQUROZ0lJSUFNZ0FEWUNDRUVBSVFCQkdDRUNRUXdMSUFOcUlBRTJBZ0FnQWlBRGFpQUFOZ0lBQzBIZ0dTZ0NBQ0lBSUFaTkRRQkI0QmtnQUNBR2F5SUJOZ0lBUWV3WlFld1pLQUlBSWdBZ0Jtb2lBallDQUNBQ0lBRkJBWEkyQWdRZ0FDQUdRUU55TmdJRUlBQkJDR29oQUF3RUMwSFFHVUV3TmdJQVFRQWhBQXdEQ3lBQUlBSTJBZ0FnQUNBQUtBSUVJQVJxTmdJRUlBSkJlQ0FDYTBFSGNXb2lDQ0FHUVFOeU5nSUVJQUZCZUNBQmEwRUhjV29pQkNBR0lBaHFJZ05ySVFjQ1FFSHNHU2dDQUNBRVJnUkFRZXdaSUFNMkFnQkI0QmxCNEJrb0FnQWdCMm9pQURZQ0FDQURJQUJCQVhJMkFnUU1BUXRCNkJrb0FnQWdCRVlFUUVIb0dTQUROZ0lBUWR3WlFkd1pLQUlBSUFkcUlnQTJBZ0FnQXlBQVFRRnlOZ0lFSUFBZ0Eyb2dBRFlDQUF3QkN5QUVLQUlFSWdCQkEzRkJBVVlFUUNBQVFYaHhJUWtnQkNnQ0RDRUNBa0FnQUVIL0FVMEVRQ0FFS0FJSUlnRWdBa1lFUUVIVUdVSFVHU2dDQUVGK0lBQkJBM1ozY1RZQ0FBd0NDeUFCSUFJMkFnd2dBaUFCTmdJSURBRUxJQVFvQWhnaEJnSkFJQUlnQkVjRVFDQUVLQUlJSWdBZ0FqWUNEQ0FDSUFBMkFnZ01BUXNDUUNBRUtBSVVJZ0FFZnlBRVFSUnFCU0FFS0FJUUlnQkZEUUVnQkVFUWFnc2hBUU5BSUFFaEJTQUFJZ0pCRkdvaEFTQUFLQUlVSWdBTkFDQUNRUkJxSVFFZ0FpZ0NFQ0lBRFFBTElBVkJBRFlDQUF3QkMwRUFJUUlMSUFaRkRRQUNRQ0FFS0FJY0lnQkJBblJCaEJ4cUlnRW9BZ0FnQkVZRVFDQUJJQUkyQWdBZ0FnMEJRZGdaUWRnWktBSUFRWDRnQUhkeE5nSUFEQUlMQWtBZ0JDQUdLQUlRUmdSQUlBWWdBallDRUF3QkN5QUdJQUkyQWhRTElBSkZEUUVMSUFJZ0JqWUNHQ0FFS0FJUUlnQUVRQ0FDSUFBMkFoQWdBQ0FDTmdJWUN5QUVLQUlVSWdCRkRRQWdBaUFBTmdJVUlBQWdBallDR0FzZ0J5QUphaUVISUFRZ0NXb2lCQ2dDQkNFQUN5QUVJQUJCZm5FMkFnUWdBeUFIUVFGeU5nSUVJQU1nQjJvZ0J6WUNBQ0FIUWY4QlRRUkFJQWRCZUhGQi9CbHFJUUFDZjBIVUdTZ0NBQ0lCUVFFZ0IwRURkblFpQW5GRkJFQkIxQmtnQVNBQ2NqWUNBQ0FBREFFTElBQW9BZ2dMSVFFZ0FDQUROZ0lJSUFFZ0F6WUNEQ0FESUFBMkFnd2dBeUFCTmdJSURBRUxRUjhoQWlBSFFmLy8vd2ROQkVBZ0IwRW1JQWRCQ0habklnQnJka0VCY1NBQVFRRjBhMEUrYWlFQ0N5QURJQUkyQWh3Z0EwSUFOd0lRSUFKQkFuUkJoQnhxSVFBQ1FBSkFRZGdaS0FJQUlnRkJBU0FDZENJRmNVVUVRRUhZR1NBQklBVnlOZ0lBSUFBZ0F6WUNBQXdCQ3lBSFFSa2dBa0VCZG10QkFDQUNRUjlIRzNRaEFpQUFLQUlBSVFFRFFDQUJJZ0FvQWdSQmVIRWdCMFlOQWlBQ1FSMTJJUUVnQWtFQmRDRUNJQUFnQVVFRWNXb2lCU2dDRUNJQkRRQUxJQVVnQXpZQ0VBc2dBeUFBTmdJWUlBTWdBellDRENBRElBTTJBZ2dNQVFzZ0FDZ0NDQ0lCSUFNMkFnd2dBQ0FETmdJSUlBTkJBRFlDR0NBRElBQTJBZ3dnQXlBQk5nSUlDeUFJUVFocUlRQU1BZ3NDUUNBSVJRMEFBa0FnQlNnQ0hDSUJRUUowUVlRY2FpSUNLQUlBSUFWR0JFQWdBaUFBTmdJQUlBQU5BVUhZR1NBSFFYNGdBWGR4SWdjMkFnQU1BZ3NDUUNBRklBZ29BaEJHQkVBZ0NDQUFOZ0lRREFFTElBZ2dBRFlDRkFzZ0FFVU5BUXNnQUNBSU5nSVlJQVVvQWhBaUFRUkFJQUFnQVRZQ0VDQUJJQUEyQWhnTElBVW9BaFFpQVVVTkFDQUFJQUUyQWhRZ0FTQUFOZ0lZQ3dKQUlBTkJEMDBFUUNBRklBTWdCbW9pQUVFRGNqWUNCQ0FBSUFWcUlnQWdBQ2dDQkVFQmNqWUNCQXdCQ3lBRklBWkJBM0kyQWdRZ0JTQUdhaUlFSUFOQkFYSTJBZ1FnQXlBRWFpQUROZ0lBSUFOQi93Rk5CRUFnQTBGNGNVSDhHV29oQUFKL1FkUVpLQUlBSWdGQkFTQURRUU4yZENJQ2NVVUVRRUhVR1NBQklBSnlOZ0lBSUFBTUFRc2dBQ2dDQ0FzaEFTQUFJQVEyQWdnZ0FTQUVOZ0lNSUFRZ0FEWUNEQ0FFSUFFMkFnZ01BUXRCSHlFQUlBTkIvLy8vQjAwRVFDQURRU1lnQTBFSWRtY2lBR3QyUVFGeElBQkJBWFJyUVQ1cUlRQUxJQVFnQURZQ0hDQUVRZ0EzQWhBZ0FFRUNkRUdFSEdvaEFRSkFBa0FnQjBFQklBQjBJZ0p4UlFSQVFkZ1pJQUlnQjNJMkFnQWdBU0FFTmdJQUlBUWdBVFlDR0F3QkN5QURRUmtnQUVFQmRtdEJBQ0FBUVI5SEczUWhBQ0FCS0FJQUlRRURRQ0FCSWdJb0FnUkJlSEVnQTBZTkFpQUFRUjEySVFFZ0FFRUJkQ0VBSUFJZ0FVRUVjV29pQnlnQ0VDSUJEUUFMSUFjZ0JEWUNFQ0FFSUFJMkFoZ0xJQVFnQkRZQ0RDQUVJQVEyQWdnTUFRc2dBaWdDQ0NJQUlBUTJBZ3dnQWlBRU5nSUlJQVJCQURZQ0dDQUVJQUkyQWd3Z0JDQUFOZ0lJQ3lBRlFRaHFJUUFNQVFzQ1FDQUpSUTBBQWtBZ0FpZ0NIQ0lCUVFKMFFZUWNhaUlGS0FJQUlBSkdCRUFnQlNBQU5nSUFJQUFOQVVIWUdTQUxRWDRnQVhkeE5nSUFEQUlMQWtBZ0FpQUpLQUlRUmdSQUlBa2dBRFlDRUF3QkN5QUpJQUEyQWhRTElBQkZEUUVMSUFBZ0NUWUNHQ0FDS0FJUUlnRUVRQ0FBSUFFMkFoQWdBU0FBTmdJWUN5QUNLQUlVSWdGRkRRQWdBQ0FCTmdJVUlBRWdBRFlDR0FzQ1FDQURRUTlOQkVBZ0FpQURJQVpxSWdCQkEzSTJBZ1FnQUNBQ2FpSUFJQUFvQWdSQkFYSTJBZ1FNQVFzZ0FpQUdRUU55TmdJRUlBSWdCbW9pQlNBRFFRRnlOZ0lFSUFNZ0JXb2dBellDQUNBSUJFQWdDRUY0Y1VIOEdXb2hBRUhvR1NnQ0FDRUJBbjlCQVNBSVFRTjJkQ0lISUFSeFJRUkFRZFFaSUFRZ0IzSTJBZ0FnQUF3QkN5QUFLQUlJQ3lFRUlBQWdBVFlDQ0NBRUlBRTJBZ3dnQVNBQU5nSU1JQUVnQkRZQ0NBdEI2QmtnQlRZQ0FFSGNHU0FETmdJQUN5QUNRUWhxSVFBTElBcEJFR29rQUNBQUN4b0FJQUFnQVNnQ0NDQUZFQXNFUUNBQklBSWdBeUFFRUJNTEN6Y0FJQUFnQVNnQ0NDQUZFQXNFUUNBQklBSWdBeUFFRUJNUEN5QUFLQUlJSWdBZ0FTQUNJQU1nQkNBRklBQW9BZ0FvQWhRUkF3QUxrUUVBSUFBZ0FTZ0NDQ0FFRUFzRVFDQUJJQUlnQXhBU0R3c0NRQ0FBSUFFb0FnQWdCQkFMUlEwQUFrQWdBU2dDRUNBQ1J3UkFJQUlnQVNnQ0ZFY05BUXNnQTBFQlJ3MEJJQUZCQVRZQ0lBOExJQUVnQWpZQ0ZDQUJJQU0yQWlBZ0FTQUJLQUlvUVFGcU5nSW9Ba0FnQVNnQ0pFRUJSdzBBSUFFb0FoaEJBa2NOQUNBQlFRRTZBRFlMSUFGQkJEWUNMQXNMOVFFQUlBQWdBU2dDQ0NBRUVBc0VRQ0FCSUFJZ0F4QVNEd3NDUUNBQUlBRW9BZ0FnQkJBTEJFQUNRQ0FCS0FJUUlBSkhCRUFnQWlBQktBSVVSdzBCQ3lBRFFRRkhEUUlnQVVFQk5nSWdEd3NnQVNBRE5nSWdBa0FnQVNnQ0xFRUVSZzBBSUFGQkFEc0JOQ0FBS0FJSUlnQWdBU0FDSUFKQkFTQUVJQUFvQWdBb0FoUVJBd0FnQVMwQU5VRUJSZ1JBSUFGQkF6WUNMQ0FCTFFBMFJRMEJEQU1MSUFGQkJEWUNMQXNnQVNBQ05nSVVJQUVnQVNnQ0tFRUJhallDS0NBQktBSWtRUUZIRFFFZ0FTZ0NHRUVDUncwQklBRkJBVG9BTmc4TElBQW9BZ2dpQUNBQklBSWdBeUFFSUFBb0FnQW9BaGdSQWdBTEN6RUFJQUFnQVNnQ0NFRUFFQXNFUUNBQklBSWdBeEFVRHdzZ0FDZ0NDQ0lBSUFFZ0FpQURJQUFvQWdBb0Fod1JBQUFMR0FBZ0FDQUJLQUlJUVFBUUN3UkFJQUVnQWlBREVCUUxDNlVGQVFaL0l3QkIwQUJySWdRa0FBSkFBbjlCQVNBQUlBRkJBQkFMRFFBYVFRQWdBVVVOQUJvakFFRVFheUlHSkFBZ0JpQUJLQUlBSWdOQkNHc29BZ0FpQlRZQ0RDQUdJQUVnQldvMkFnUWdCaUFEUVFScktBSUFOZ0lJSUFZb0FnZ2lBMEhJQ0VFQUVBc2hCU0FHS0FJRUlRY0NRQ0FGQkVBZ0JpZ0NEQ0VCSXdCQlFHb2lBeVFBSUFOQlFHc2tBRUVBSUFjZ0FSc2hBd3dCQ3lBRElRVWpBRUZBYWlJREpBQWdBU0FIVGdSQUlBTkNBRGNDSENBRFFnQTNBaVFnQTBJQU53SXNJQU5DQURjQ0ZDQURRUUEyQWhBZ0EwSElDRFlDRENBRElBVTJBZ1FnQTBFQU5nSThJQU5DZ1lDQWdJQ0FnSUFCTndJMElBTWdBVFlDQ0NBRklBTkJCR29nQnlBSFFRRkJBQ0FGS0FJQUtBSVVFUU1BSUFGQkFDQURLQUljR3lFSUN5QURRVUJySkFBZ0NDSUREUUFqQUVGQWFpSURKQUFnQTBFQU5nSVFJQU5CbUFnMkFnd2dBeUFCTmdJSUlBTkJ5QWcyQWdSQkFDRUJJQU5CRkdwQkFFRW4vQXNBSUFOQkFEWUNQQ0FEUVFFNkFEc2dCU0FEUVFScUlBZEJBVUVBSUFVb0FnQW9BaGdSQWdBQ1FBSkFBa0FnQXlnQ0tBNENBQUVDQ3lBREtBSVlRUUFnQXlnQ0pFRUJSaHRCQUNBREtBSWdRUUZHRzBFQUlBTW9BaXhCQVVZYklRRU1BUXNnQXlnQ0hFRUJSd1JBSUFNb0Fpd05BU0FES0FJZ1FRRkhEUUVnQXlnQ0pFRUJSdzBCQ3lBREtBSVVJUUVMSUFOQlFHc2tBQ0FCSVFNTElBWkJFR29rQUVFQUlBTkZEUUFhSUFJb0FnQWlBVVVOQVNBRVFSaHFRUUJCT1B3TEFDQUVRUUU2QUVzZ0JFRi9OZ0lnSUFRZ0FEWUNIQ0FFSUFNMkFoUWdCRUVCTmdKRUlBTWdCRUVVYWlBQlFRRWdBeWdDQUNnQ0hCRUFBQ0FFS0FJc0lnQkJBVVlFUUNBQ0lBUW9BaVEyQWdBTElBQkJBVVlMSUFSQjBBQnFKQUFQQ3lBRVFjOEtOZ0lJSUFSQjVRTTJBZ1FnQkVHNUNUWUNBQkFKQUFzS0FDQUFJQUZCQUJBTEM4WUVBZ1ovQ24xQi8vLy8vd2NoREVHQWdJQ0FlQ0VOUVg4aENRTkFJQU1nQ2tZRVFFRUFJUUFnQ0VFQVFZQ0FFUHdMQUVNQS8zOUhJQTBnREd1eWxTRVBCU0FFSUFwQkRHeHFJZ3NxQWdBaEV5QUxLZ0lJSVJRZ0N5b0NCQ0VWSUFrZ0FpQUtRUUowSWc1cUtBSUFJZ3RIQkVBZ0FTQUxRZEFBYkdvaUNTb0NQQ0FBS2dJNElnK1VJQWtxQWpnZ0FDb0NLQ0lRbENBSktnSXdJQUFxQWdnaUVaUWdBQ29DR0NJU0lBa3FBalNVa3BLU0lSWWdDU29DTENBUGxDQUpLZ0lvSUJDVUlBa3FBaUFnRVpRZ0VpQUpLZ0lrbEpLU2tpRVhJQWtxQWh3Z0Q1UWdDU29DR0NBUWxDQUpLZ0lRSUJHVUlCSWdDU29DRkpTU2twSWhHQ0FKS2dJTUlBK1VJQWtxQWdnZ0VKUWdDU29DQUNBUmxDQUpLZ0lFSUJLVWtwS1NJUThnQ3lFSkN5QUZJQTVxSUJZZ0Z5QVVsQ0FQSUJPVUlCVWdHSlNTa3BKREFBQ0FSWlQ4QUNJTE5nSUFJQXdnQ3lBTElBeEtHeUVNSUEwZ0N5QUxJQTFJR3lFTklBcEJBV29oQ2d3QkN3c0RRQ0FBSUFOR1JRUkFJQVVnQUVFQ2RHb2lBU0FQSUFFb0FnQWdER3V6bFB3QklnRTJBZ0FnQ0NBQlFRSjBhaUlCSUFFb0FnQkJBV28yQWdBZ0FFRUJhaUVBREFFTEMwRUFJUUFnQjBFQU5nSUFJQWhCQkdzaEFVRUFJUXhCQVNFS0EwQWdDa0dBZ0FSR0JFQURRQUpBSUFBZ0EwWU5BQ0FISUFVZ0FFRUNkR29vQWdCQkFuUnFJZ0VnQVNnQ0FDSUJRUUZxTmdJQUlBWWdBVUVDZEdvZ0FEWUNBQ0FBUVFGcUlRQU1BUXNMQlNBSElBcEJBblFpQW1vZ0FTQUNhaWdDQUNBTWFpSU1OZ0lBSUFwQkFXb2hDZ3dCQ3dzTEM5c1JBZ0JCZ0FnTHloRUVDUUFBQ0FRQUFGTjBPWFI1Y0dWZmFXNW1id0FBQUFBc0NRQUFKQVFBQUFBRUFBQk9NVEJmWDJONGVHRmlhWFl4TVRaZlgzTm9hVzFmZEhsd1pWOXBibVp2UlFBQUFBQXNDUUFBVkFRQUFCZ0VBQUJPTVRCZlgyTjRlR0ZpYVhZeE1UZGZYMk5zWVhOelgzUjVjR1ZmYVc1bWIwVUFkVzV6YVdkdVpXUWdjMmh2Y25RQWRXNXphV2R1WldRZ2FXNTBBR1pzYjJGMEFIVnBiblEyTkY5MEFDVnpPaVZrT2lBbGN3QjFibk5wWjI1bFpDQmphR0Z5QUM5bGJYTmtheTlsYlhOamNtbHdkR1Z1TDNONWMzUmxiUzlzYVdJdmJHbGlZM2g0WVdKcEwzTnlZeTl3Y21sMllYUmxYM1I1Y0dWcGJtWnZMbU53Y0FCaWIyOXNBSFZ1YzJsbmJtVmtJR3h2Ym1jQWMzUmtPanAzYzNSeWFXNW5BSE4wWkRvNmMzUnlhVzVuQUhOMFpEbzZkVEUyYzNSeWFXNW5BSE4wWkRvNmRUTXljM1J5YVc1bkFHUnZkV0pzWlFCMmIybGtBR05oZEdOb2FXNW5JR0VnWTJ4aGMzTWdkMmwwYUc5MWRDQmhiaUJ2WW1wbFkzUS9BR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BITm9iM0owUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYm5OcFoyNWxaQ0J6YUc5eWRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGFXNTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eDFibk5wWjI1bFpDQnBiblErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR1pzYjJGMFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4MWFXNTBPRjkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenhwYm5RNFgzUStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BIVnBiblF4Tmw5MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4cGJuUXhObDkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYVc1ME5qUmZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhhVzUwTmpSZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXbHVkRE15WDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEdsdWRETXlYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR05vWVhJK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEhWdWMybG5ibVZrSUdOb1lYSStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BITnBaMjVsWkNCamFHRnlQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eHNiMjVuUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYm5OcFoyNWxaQ0JzYjI1blBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4a2IzVmliR1UrQUFBQUFBQUFBQUFVQ0FBQUFRQUFBQUlBQUFBREFBQUFCQUFBQUFVQUFBQXNDUUFBSUFnQUFCZ0VBQUJPTVRCZlgyTjRlR0ZpYVhZeE1qTmZYMloxYm1SaGJXVnVkR0ZzWDNSNWNHVmZhVzVtYjBVQUFBZ0FBRkFJQUFCMkFBQUFBQWdBQUZ3SUFBQmlBQUFBQUFnQUFHZ0lBQUJqQUFBQUFBZ0FBSFFJQUFCb0FBQUFBQWdBQUlBSUFBQmhBQUFBQUFnQUFJd0lBQUJ6QUFBQUFBZ0FBSmdJQUFCMEFBQUFBQWdBQUtRSUFBQnBBQUFBQUFnQUFMQUlBQUJxQUFBQUFBZ0FBTHdJQUFCc0FBQUFBQWdBQU1nSUFBQnRBQUFBQUFnQUFOUUlBQUI0QUFBQUFBZ0FBT0FJQUFCNUFBQUFBQWdBQU93SUFBQm1BQUFBQUFnQUFQZ0lBQUJrQUFBQUFBQUFBRWdFQUFBQkFBQUFCZ0FBQUFNQUFBQUVBQUFBQndBQUFBZ0FBQUFKQUFBQUNnQUFBQUFBQUFCTUNRQUFBUUFBQUFzQUFBQURBQUFBQkFBQUFBY0FBQUFNQUFBQURRQUFBQTRBQUFBc0NRQUFXQWtBQUVnRUFBQk9NVEJmWDJONGVHRmlhWFl4TWpCZlgzTnBYMk5zWVhOelgzUjVjR1ZmYVc1bWIwVUFBQUFBQkFrQUFJZ0pBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSlkwNVRYekV4WTJoaGNsOTBjbUZwZEhOSlkwVkZUbE5mT1dGc2JHOWpZWFJ2Y2tsalJVVkZSUUFBQkFrQUFOQUpBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSmQwNVRYekV4WTJoaGNsOTBjbUZwZEhOSmQwVkZUbE5mT1dGc2JHOWpZWFJ2Y2tsM1JVVkZSUUFBQkFrQUFCZ0tBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSlJITk9VMTh4TVdOb1lYSmZkSEpoYVhSelNVUnpSVVZPVTE4NVlXeHNiMk5oZEc5eVNVUnpSVVZGUlFBQUFBUUpBQUJrQ2dBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TVVJwVGxOZk1URmphR0Z5WDNSeVlXbDBjMGxFYVVWRlRsTmZPV0ZzYkc5allYUnZja2xFYVVWRlJVVUFBQUFFQ1FBQXNBb0FBRTR4TUdWdGMyTnlhWEIwWlc0emRtRnNSUUFBQkFrQUFNd0tBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGxqUlVVQUFBUUpBQUQwQ2dBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSllVVkZBQUFFQ1FBQUhBc0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV2hGUlFBQUJBa0FBRVFMQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBselJVVUFBQVFKQUFCc0N3QUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpkRVZGQUFBRUNRQUFsQXNBQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1dsRlJRQUFCQWtBQUx3TEFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbHFSVVVBQUFRSkFBRGtDd0FBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKYkVWRkFBQUVDUUFBREF3QUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXMUZSUUFBQkFrQUFEUU1BQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGw0UlVVQUFBUUpBQUJjREFBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmVVVkZBQUFFQ1FBQWhBd0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV1pGUlFBQUJBa0FBS3dNQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsa1JVVUFRY3daQ3dQUURnRT0iO2Z1bmN0aW9uIGdldEJpbmFyeVN5bmMoZmlsZSl7aWYoZmlsZT09d2FzbUJpbmFyeUZpbGUmJndhc21CaW5hcnkpe3JldHVybiBuZXcgVWludDhBcnJheSh3YXNtQmluYXJ5KX12YXIgYmluYXJ5PXRyeVBhcnNlQXNEYXRhVVJJKGZpbGUpO2lmKGJpbmFyeSl7cmV0dXJuIGJpbmFyeX1pZihyZWFkQmluYXJ5KXtyZXR1cm4gcmVhZEJpbmFyeShmaWxlKX10aHJvdyAiYm90aCBhc3luYyBhbmQgc3luYyBmZXRjaGluZyBvZiB0aGUgd2FzbSBmYWlsZWQifWFzeW5jIGZ1bmN0aW9uIGdldFdhc21CaW5hcnkoYmluYXJ5RmlsZSl7cmV0dXJuIGdldEJpbmFyeVN5bmMoYmluYXJ5RmlsZSl9YXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpe3RyeXt2YXIgYmluYXJ5PWF3YWl0IGdldFdhc21CaW5hcnkoYmluYXJ5RmlsZSk7dmFyIGluc3RhbmNlPWF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJpbmFyeSxpbXBvcnRzKTtyZXR1cm4gaW5zdGFuY2V9Y2F0Y2gocmVhc29uKXtlcnIoYGZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206ICR7cmVhc29ufWApO2Fib3J0KHJlYXNvbik7fX1hc3luYyBmdW5jdGlvbiBpbnN0YW50aWF0ZUFzeW5jKGJpbmFyeSxiaW5hcnlGaWxlLGltcG9ydHMpe3JldHVybiBpbnN0YW50aWF0ZUFycmF5QnVmZmVyKGJpbmFyeUZpbGUsaW1wb3J0cyl9ZnVuY3Rpb24gZ2V0V2FzbUltcG9ydHMoKXtyZXR1cm4ge2E6d2FzbUltcG9ydHN9fWFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdhc20oKXtmdW5jdGlvbiByZWNlaXZlSW5zdGFuY2UoaW5zdGFuY2UsbW9kdWxlKXt3YXNtRXhwb3J0cz1pbnN0YW5jZS5leHBvcnRzO3dhc21NZW1vcnk9d2FzbUV4cG9ydHNbImwiXTt1cGRhdGVNZW1vcnlWaWV3cygpO3JlbW92ZVJ1bkRlcGVuZGVuY3koKTtyZXR1cm4gd2FzbUV4cG9ydHN9YWRkUnVuRGVwZW5kZW5jeSgpO2Z1bmN0aW9uIHJlY2VpdmVJbnN0YW50aWF0aW9uUmVzdWx0KHJlc3VsdCl7cmV0dXJuIHJlY2VpdmVJbnN0YW5jZShyZXN1bHRbImluc3RhbmNlIl0pfXZhciBpbmZvPWdldFdhc21JbXBvcnRzKCk7aWYoTW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXSl7cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLHJlamVjdCk9PntNb2R1bGVbImluc3RhbnRpYXRlV2FzbSJdKGluZm8sKG1vZCxpbnN0KT0+e3JlY2VpdmVJbnN0YW5jZShtb2QpO3Jlc29sdmUobW9kLmV4cG9ydHMpO30pO30pfXRyeXt2YXIgcmVzdWx0PWF3YWl0IGluc3RhbnRpYXRlQXN5bmMod2FzbUJpbmFyeSx3YXNtQmluYXJ5RmlsZSxpbmZvKTt2YXIgZXhwb3J0cz1yZWNlaXZlSW5zdGFudGlhdGlvblJlc3VsdChyZXN1bHQpO3JldHVybiBleHBvcnRzfWNhdGNoKGUpe3JlYWR5UHJvbWlzZVJlamVjdChlKTtyZXR1cm4gUHJvbWlzZS5yZWplY3QoZSl9fXZhciBjYWxsUnVudGltZUNhbGxiYWNrcz1jYWxsYmFja3M9Pnt3aGlsZShjYWxsYmFja3MubGVuZ3RoPjApe2NhbGxiYWNrcy5zaGlmdCgpKE1vZHVsZSk7fX07dmFyIG9uUG9zdFJ1bnM9W107dmFyIGFkZE9uUG9zdFJ1bj1jYj0+b25Qb3N0UnVucy51bnNoaWZ0KGNiKTt2YXIgb25QcmVSdW5zPVtdO3ZhciBhZGRPblByZVJ1bj1jYj0+b25QcmVSdW5zLnVuc2hpZnQoY2IpO01vZHVsZVsibm9FeGl0UnVudGltZSJdfHx0cnVlO3ZhciBiYXNlNjREZWNvZGU9YjY0PT57dmFyIGIxLGIyLGk9MCxqPTAsYkxlbmd0aD1iNjQubGVuZ3RoO3ZhciBvdXRwdXQ9bmV3IFVpbnQ4QXJyYXkoKGJMZW5ndGgqMz4+MiktKGI2NFtiTGVuZ3RoLTJdPT0iPSIpLShiNjRbYkxlbmd0aC0xXT09Ij0iKSk7Zm9yKDtpPGJMZW5ndGg7aSs9NCxqKz0zKXtiMT1iYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldO2IyPWJhc2U2NFJldmVyc2VMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsyKV07b3V0cHV0W2pdPWJhc2U2NFJldmVyc2VMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldPDwyfGIxPj40O291dHB1dFtqKzFdPWIxPDw0fGIyPj4yO291dHB1dFtqKzJdPWIyPDw2fGJhc2U2NFJldmVyc2VMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSszKV07fXJldHVybiBvdXRwdXR9O3ZhciBpc0RhdGFVUkk9ZmlsZW5hbWU9PmZpbGVuYW1lLnN0YXJ0c1dpdGgoZGF0YVVSSVByZWZpeCk7dmFyIGRhdGFVUklQcmVmaXg9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCwiO3ZhciB0cnlQYXJzZUFzRGF0YVVSST1maWxlbmFtZT0+e2lmKGlzRGF0YVVSSShmaWxlbmFtZSkpe3JldHVybiBiYXNlNjREZWNvZGUoZmlsZW5hbWUuc2xpY2UoZGF0YVVSSVByZWZpeC5sZW5ndGgpKX19O3ZhciBfX2Fib3J0X2pzPSgpPT5hYm9ydCgiIik7dmFyIGVtYmluZFJlcHI9dj0+e2lmKHY9PT1udWxsKXtyZXR1cm4gIm51bGwifXZhciB0PXR5cGVvZiB2O2lmKHQ9PT0ib2JqZWN0Inx8dD09PSJhcnJheSJ8fHQ9PT0iZnVuY3Rpb24iKXtyZXR1cm4gdi50b1N0cmluZygpfWVsc2Uge3JldHVybiAiIit2fX07dmFyIGVtYmluZF9pbml0X2NoYXJDb2Rlcz0oKT0+e3ZhciBjb2Rlcz1uZXcgQXJyYXkoMjU2KTtmb3IodmFyIGk9MDtpPDI1NjsrK2kpe2NvZGVzW2ldPVN0cmluZy5mcm9tQ2hhckNvZGUoaSk7fWVtYmluZF9jaGFyQ29kZXM9Y29kZXM7fTt2YXIgZW1iaW5kX2NoYXJDb2Rlczt2YXIgcmVhZExhdGluMVN0cmluZz1wdHI9Pnt2YXIgcmV0PSIiO3ZhciBjPXB0cjt3aGlsZShIRUFQVThbY10pe3JldCs9ZW1iaW5kX2NoYXJDb2Rlc1tIRUFQVThbYysrXV07fXJldHVybiByZXR9O3ZhciBhd2FpdGluZ0RlcGVuZGVuY2llcz17fTt2YXIgcmVnaXN0ZXJlZFR5cGVzPXt9O3ZhciBCaW5kaW5nRXJyb3I7dmFyIHRocm93QmluZGluZ0Vycm9yPW1lc3NhZ2U9Pnt0aHJvdyBuZXcgQmluZGluZ0Vycm9yKG1lc3NhZ2UpfTtmdW5jdGlvbiBzaGFyZWRSZWdpc3RlclR5cGUocmF3VHlwZSxyZWdpc3RlcmVkSW5zdGFuY2Usb3B0aW9ucz17fSl7dmFyIG5hbWU9cmVnaXN0ZXJlZEluc3RhbmNlLm5hbWU7aWYoIXJhd1R5cGUpe3Rocm93QmluZGluZ0Vycm9yKGB0eXBlICIke25hbWV9IiBtdXN0IGhhdmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIHR5cGVpZCBwb2ludGVyYCk7fWlmKHJlZ2lzdGVyZWRUeXBlcy5oYXNPd25Qcm9wZXJ0eShyYXdUeXBlKSl7aWYob3B0aW9ucy5pZ25vcmVEdXBsaWNhdGVSZWdpc3RyYXRpb25zKXtyZXR1cm59ZWxzZSB7dGhyb3dCaW5kaW5nRXJyb3IoYENhbm5vdCByZWdpc3RlciB0eXBlICcke25hbWV9JyB0d2ljZWApO319cmVnaXN0ZXJlZFR5cGVzW3Jhd1R5cGVdPXJlZ2lzdGVyZWRJbnN0YW5jZTtpZihhd2FpdGluZ0RlcGVuZGVuY2llcy5oYXNPd25Qcm9wZXJ0eShyYXdUeXBlKSl7dmFyIGNhbGxiYWNrcz1hd2FpdGluZ0RlcGVuZGVuY2llc1tyYXdUeXBlXTtkZWxldGUgYXdhaXRpbmdEZXBlbmRlbmNpZXNbcmF3VHlwZV07Y2FsbGJhY2tzLmZvckVhY2goY2I9PmNiKCkpO319ZnVuY3Rpb24gcmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnM9e30pe3JldHVybiBzaGFyZWRSZWdpc3RlclR5cGUocmF3VHlwZSxyZWdpc3RlcmVkSW5zdGFuY2Usb3B0aW9ucyl9dmFyIGludGVnZXJSZWFkVmFsdWVGcm9tUG9pbnRlcj0obmFtZSx3aWR0aCxzaWduZWQpPT57c3dpdGNoKHdpZHRoKXtjYXNlIDE6cmV0dXJuIHNpZ25lZD9wb2ludGVyPT5IRUFQOFtwb2ludGVyXTpwb2ludGVyPT5IRUFQVThbcG9pbnRlcl07Y2FzZSAyOnJldHVybiBzaWduZWQ/cG9pbnRlcj0+SEVBUDE2W3BvaW50ZXI+PjFdOnBvaW50ZXI9PkhFQVBVMTZbcG9pbnRlcj4+MV07Y2FzZSA0OnJldHVybiBzaWduZWQ/cG9pbnRlcj0+SEVBUDMyW3BvaW50ZXI+PjJdOnBvaW50ZXI9PkhFQVBVMzJbcG9pbnRlcj4+Ml07Y2FzZSA4OnJldHVybiBzaWduZWQ/cG9pbnRlcj0+SEVBUDY0W3BvaW50ZXI+PjNdOnBvaW50ZXI9PkhFQVBVNjRbcG9pbnRlcj4+M107ZGVmYXVsdDp0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnZhbGlkIGludGVnZXIgd2lkdGggKCR7d2lkdGh9KTogJHtuYW1lfWApfX07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludD0ocHJpbWl0aXZlVHlwZSxuYW1lLHNpemUsbWluUmFuZ2UsbWF4UmFuZ2UpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBpc1Vuc2lnbmVkVHlwZT1uYW1lLmluZGV4T2YoInUiKSE9LTE7cmVnaXN0ZXJUeXBlKHByaW1pdGl2ZVR5cGUse25hbWUsZnJvbVdpcmVUeXBlOnZhbHVlPT52YWx1ZSx0b1dpcmVUeXBlOmZ1bmN0aW9uKGRlc3RydWN0b3JzLHZhbHVlKXtpZih0eXBlb2YgdmFsdWUhPSJiaWdpbnQiJiZ0eXBlb2YgdmFsdWUhPSJudW1iZXIiKXt0aHJvdyBuZXcgVHlwZUVycm9yKGBDYW5ub3QgY29udmVydCAiJHtlbWJpbmRSZXByKHZhbHVlKX0iIHRvICR7dGhpcy5uYW1lfWApfWlmKHR5cGVvZiB2YWx1ZT09Im51bWJlciIpe3ZhbHVlPUJpZ0ludCh2YWx1ZSk7fXJldHVybiB2YWx1ZX0sYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjppbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXIobmFtZSxzaXplLCFpc1Vuc2lnbmVkVHlwZSksZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9KTt9O3ZhciBHZW5lcmljV2lyZVR5cGVTaXplPTg7dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2Jvb2w9KHJhd1R5cGUsbmFtZSx0cnVlVmFsdWUsZmFsc2VWYWx1ZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWUsZnJvbVdpcmVUeXBlOmZ1bmN0aW9uKHd0KXtyZXR1cm4gISF3dH0sdG9XaXJlVHlwZTpmdW5jdGlvbihkZXN0cnVjdG9ycyxvKXtyZXR1cm4gbz90cnVlVmFsdWU6ZmFsc2VWYWx1ZX0sYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUFU4W3BvaW50ZXJdKX0sZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9KTt9O3ZhciBlbXZhbF9mcmVlbGlzdD1bXTt2YXIgZW12YWxfaGFuZGxlcz1bXTt2YXIgX19lbXZhbF9kZWNyZWY9aGFuZGxlPT57aWYoaGFuZGxlPjkmJjA9PT0tLWVtdmFsX2hhbmRsZXNbaGFuZGxlKzFdKXtlbXZhbF9oYW5kbGVzW2hhbmRsZV09dW5kZWZpbmVkO2VtdmFsX2ZyZWVsaXN0LnB1c2goaGFuZGxlKTt9fTt2YXIgY291bnRfZW12YWxfaGFuZGxlcz0oKT0+ZW12YWxfaGFuZGxlcy5sZW5ndGgvMi01LWVtdmFsX2ZyZWVsaXN0Lmxlbmd0aDt2YXIgaW5pdF9lbXZhbD0oKT0+e2VtdmFsX2hhbmRsZXMucHVzaCgwLDEsdW5kZWZpbmVkLDEsbnVsbCwxLHRydWUsMSxmYWxzZSwxKTtNb2R1bGVbImNvdW50X2VtdmFsX2hhbmRsZXMiXT1jb3VudF9lbXZhbF9oYW5kbGVzO307dmFyIEVtdmFsPXt0b1ZhbHVlOmhhbmRsZT0+e2lmKCFoYW5kbGUpe3Rocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgdXNlIGRlbGV0ZWQgdmFsLiBoYW5kbGUgPSAiK2hhbmRsZSk7fXJldHVybiBlbXZhbF9oYW5kbGVzW2hhbmRsZV19LHRvSGFuZGxlOnZhbHVlPT57c3dpdGNoKHZhbHVlKXtjYXNlIHVuZGVmaW5lZDpyZXR1cm4gMjtjYXNlIG51bGw6cmV0dXJuIDQ7Y2FzZSB0cnVlOnJldHVybiA2O2Nhc2UgZmFsc2U6cmV0dXJuIDg7ZGVmYXVsdDp7Y29uc3QgaGFuZGxlPWVtdmFsX2ZyZWVsaXN0LnBvcCgpfHxlbXZhbF9oYW5kbGVzLmxlbmd0aDtlbXZhbF9oYW5kbGVzW2hhbmRsZV09dmFsdWU7ZW12YWxfaGFuZGxlc1toYW5kbGUrMV09MTtyZXR1cm4gaGFuZGxlfX19fTtmdW5jdGlvbiByZWFkUG9pbnRlcihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUFUzMltwb2ludGVyPj4yXSl9dmFyIEVtVmFsVHlwZT17bmFtZToiZW1zY3JpcHRlbjo6dmFsIixmcm9tV2lyZVR5cGU6aGFuZGxlPT57dmFyIHJ2PUVtdmFsLnRvVmFsdWUoaGFuZGxlKTtfX2VtdmFsX2RlY3JlZihoYW5kbGUpO3JldHVybiBydn0sdG9XaXJlVHlwZTooZGVzdHJ1Y3RvcnMsdmFsdWUpPT5FbXZhbC50b0hhbmRsZSh2YWx1ZSksYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpyZWFkUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2VtdmFsPXJhd1R5cGU9PnJlZ2lzdGVyVHlwZShyYXdUeXBlLEVtVmFsVHlwZSk7dmFyIGZsb2F0UmVhZFZhbHVlRnJvbVBvaW50ZXI9KG5hbWUsd2lkdGgpPT57c3dpdGNoKHdpZHRoKXtjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9uKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQRjMyW3BvaW50ZXI+PjJdKX07Y2FzZSA4OnJldHVybiBmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEY2NFtwb2ludGVyPj4zXSl9O2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCBmbG9hdCB3aWR0aCAoJHt3aWR0aH0pOiAke25hbWV9YCl9fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfZmxvYXQ9KHJhd1R5cGUsbmFtZSxzaXplKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTtyZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZSxmcm9tV2lyZVR5cGU6dmFsdWU9PnZhbHVlLHRvV2lyZVR5cGU6KGRlc3RydWN0b3JzLHZhbHVlKT0+dmFsdWUsYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpmbG9hdFJlYWRWYWx1ZUZyb21Qb2ludGVyKG5hbWUsc2l6ZSksZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9KTt9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9pbnRlZ2VyPShwcmltaXRpdmVUeXBlLG5hbWUsc2l6ZSxtaW5SYW5nZSxtYXhSYW5nZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7dmFyIGZyb21XaXJlVHlwZT12YWx1ZT0+dmFsdWU7aWYobWluUmFuZ2U9PT0wKXt2YXIgYml0c2hpZnQ9MzItOCpzaXplO2Zyb21XaXJlVHlwZT12YWx1ZT0+dmFsdWU8PGJpdHNoaWZ0Pj4+Yml0c2hpZnQ7fXZhciBpc1Vuc2lnbmVkVHlwZT1uYW1lLmluY2x1ZGVzKCJ1bnNpZ25lZCIpO3ZhciBjaGVja0Fzc2VydGlvbnM9KHZhbHVlLHRvVHlwZU5hbWUpPT57fTt2YXIgdG9XaXJlVHlwZTtpZihpc1Vuc2lnbmVkVHlwZSl7dG9XaXJlVHlwZT1mdW5jdGlvbihkZXN0cnVjdG9ycyx2YWx1ZSl7Y2hlY2tBc3NlcnRpb25zKHZhbHVlLHRoaXMubmFtZSk7cmV0dXJuIHZhbHVlPj4+MH07fWVsc2Uge3RvV2lyZVR5cGU9ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsdmFsdWUpe2NoZWNrQXNzZXJ0aW9ucyh2YWx1ZSx0aGlzLm5hbWUpO3JldHVybiB2YWx1ZX07fXJlZ2lzdGVyVHlwZShwcmltaXRpdmVUeXBlLHtuYW1lLGZyb21XaXJlVHlwZSx0b1dpcmVUeXBlLGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6aW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyKG5hbWUsc2l6ZSxtaW5SYW5nZSE9PTApLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfbWVtb3J5X3ZpZXc9KHJhd1R5cGUsZGF0YVR5cGVJbmRleCxuYW1lKT0+e3ZhciB0eXBlTWFwcGluZz1bSW50OEFycmF5LFVpbnQ4QXJyYXksSW50MTZBcnJheSxVaW50MTZBcnJheSxJbnQzMkFycmF5LFVpbnQzMkFycmF5LEZsb2F0MzJBcnJheSxGbG9hdDY0QXJyYXksQmlnSW50NjRBcnJheSxCaWdVaW50NjRBcnJheV07dmFyIFRBPXR5cGVNYXBwaW5nW2RhdGFUeXBlSW5kZXhdO2Z1bmN0aW9uIGRlY29kZU1lbW9yeVZpZXcoaGFuZGxlKXt2YXIgc2l6ZT1IRUFQVTMyW2hhbmRsZT4+Ml07dmFyIGRhdGE9SEVBUFUzMltoYW5kbGUrND4+Ml07cmV0dXJuIG5ldyBUQShIRUFQOC5idWZmZXIsZGF0YSxzaXplKX1uYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWUsZnJvbVdpcmVUeXBlOmRlY29kZU1lbW9yeVZpZXcsYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpkZWNvZGVNZW1vcnlWaWV3fSx7aWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9uczp0cnVlfSk7fTt2YXIgc3RyaW5nVG9VVEY4QXJyYXk9KHN0cixoZWFwLG91dElkeCxtYXhCeXRlc1RvV3JpdGUpPT57aWYoIShtYXhCeXRlc1RvV3JpdGU+MCkpcmV0dXJuIDA7dmFyIHN0YXJ0SWR4PW91dElkeDt2YXIgZW5kSWR4PW91dElkeCttYXhCeXRlc1RvV3JpdGUtMTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgdT1zdHIuY2hhckNvZGVBdChpKTtpZih1Pj01NTI5NiYmdTw9NTczNDMpe3ZhciB1MT1zdHIuY2hhckNvZGVBdCgrK2kpO3U9NjU1MzYrKCh1JjEwMjMpPDwxMCl8dTEmMTAyMzt9aWYodTw9MTI3KXtpZihvdXRJZHg+PWVuZElkeClicmVhaztoZWFwW291dElkeCsrXT11O31lbHNlIGlmKHU8PTIwNDcpe2lmKG91dElkeCsxPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MTkyfHU+PjY7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fWVsc2UgaWYodTw9NjU1MzUpe2lmKG91dElkeCsyPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MjI0fHU+PjEyO2hlYXBbb3V0SWR4KytdPTEyOHx1Pj42JjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO31lbHNlIHtpZihvdXRJZHgrMz49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTI0MHx1Pj4xODtoZWFwW291dElkeCsrXT0xMjh8dT4+MTImNjM7aGVhcFtvdXRJZHgrK109MTI4fHU+PjYmNjM7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fX1oZWFwW291dElkeF09MDtyZXR1cm4gb3V0SWR4LXN0YXJ0SWR4fTt2YXIgc3RyaW5nVG9VVEY4PShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PnN0cmluZ1RvVVRGOEFycmF5KHN0cixIRUFQVTgsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk7dmFyIGxlbmd0aEJ5dGVzVVRGOD1zdHI9Pnt2YXIgbGVuPTA7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGM9c3RyLmNoYXJDb2RlQXQoaSk7aWYoYzw9MTI3KXtsZW4rKzt9ZWxzZSBpZihjPD0yMDQ3KXtsZW4rPTI7fWVsc2UgaWYoYz49NTUyOTYmJmM8PTU3MzQzKXtsZW4rPTQ7KytpO31lbHNlIHtsZW4rPTM7fX1yZXR1cm4gbGVufTt2YXIgVVRGOERlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXI6dW5kZWZpbmVkO3ZhciBVVEY4QXJyYXlUb1N0cmluZz0oaGVhcE9yQXJyYXksaWR4PTAsbWF4Qnl0ZXNUb1JlYWQ9TmFOKT0+e3ZhciBlbmRJZHg9aWR4K21heEJ5dGVzVG9SZWFkO3ZhciBlbmRQdHI9aWR4O3doaWxlKGhlYXBPckFycmF5W2VuZFB0cl0mJiEoZW5kUHRyPj1lbmRJZHgpKSsrZW5kUHRyO2lmKGVuZFB0ci1pZHg+MTYmJmhlYXBPckFycmF5LmJ1ZmZlciYmVVRGOERlY29kZXIpe3JldHVybiBVVEY4RGVjb2Rlci5kZWNvZGUoaGVhcE9yQXJyYXkuc3ViYXJyYXkoaWR4LGVuZFB0cikpfXZhciBzdHI9IiI7d2hpbGUoaWR4PGVuZFB0cil7dmFyIHUwPWhlYXBPckFycmF5W2lkeCsrXTtpZighKHUwJjEyOCkpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1MCk7Y29udGludWV9dmFyIHUxPWhlYXBPckFycmF5W2lkeCsrXSY2MztpZigodTAmMjI0KT09MTkyKXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoKHUwJjMxKTw8Nnx1MSk7Y29udGludWV9dmFyIHUyPWhlYXBPckFycmF5W2lkeCsrXSY2MztpZigodTAmMjQwKT09MjI0KXt1MD0odTAmMTUpPDwxMnx1MTw8Nnx1Mjt9ZWxzZSB7dTA9KHUwJjcpPDwxOHx1MTw8MTJ8dTI8PDZ8aGVhcE9yQXJyYXlbaWR4KytdJjYzO31pZih1MDw2NTUzNil7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHUwKTt9ZWxzZSB7dmFyIGNoPXUwLTY1NTM2O3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxjaD4+MTAsNTYzMjB8Y2gmMTAyMyk7fX1yZXR1cm4gc3RyfTt2YXIgVVRGOFRvU3RyaW5nPShwdHIsbWF4Qnl0ZXNUb1JlYWQpPT5wdHI/VVRGOEFycmF5VG9TdHJpbmcoSEVBUFU4LHB0cixtYXhCeXRlc1RvUmVhZCk6IiI7dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF9zdHJpbmc9KHJhd1R5cGUsbmFtZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWUsZnJvbVdpcmVUeXBlKHZhbHVlKXt2YXIgbGVuZ3RoPUhFQVBVMzJbdmFsdWU+PjJdO3ZhciBwYXlsb2FkPXZhbHVlKzQ7dmFyIHN0cjt2YXIgaTsge3ZhciBkZWNvZGVTdGFydFB0cj1wYXlsb2FkO2Zvcih2YXIgaT0wO2k8PWxlbmd0aDsrK2kpe3ZhciBjdXJyZW50Qnl0ZVB0cj1wYXlsb2FkK2k7aWYoaT09bGVuZ3RofHxIRUFQVThbY3VycmVudEJ5dGVQdHJdPT0wKXt2YXIgbWF4UmVhZD1jdXJyZW50Qnl0ZVB0ci1kZWNvZGVTdGFydFB0cjt2YXIgc3RyaW5nU2VnbWVudD1VVEY4VG9TdHJpbmcoZGVjb2RlU3RhcnRQdHIsbWF4UmVhZCk7aWYoc3RyPT09dW5kZWZpbmVkKXtzdHI9c3RyaW5nU2VnbWVudDt9ZWxzZSB7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDApO3N0cis9c3RyaW5nU2VnbWVudDt9ZGVjb2RlU3RhcnRQdHI9Y3VycmVudEJ5dGVQdHIrMTt9fX1fZnJlZSh2YWx1ZSk7cmV0dXJuIHN0cn0sdG9XaXJlVHlwZShkZXN0cnVjdG9ycyx2YWx1ZSl7aWYodmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcil7dmFsdWU9bmV3IFVpbnQ4QXJyYXkodmFsdWUpO312YXIgbGVuZ3RoO3ZhciB2YWx1ZUlzT2ZUeXBlU3RyaW5nPXR5cGVvZiB2YWx1ZT09InN0cmluZyI7aWYoISh2YWx1ZUlzT2ZUeXBlU3RyaW5nfHx2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fHZhbHVlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXl8fHZhbHVlIGluc3RhbmNlb2YgSW50OEFycmF5KSl7dGhyb3dCaW5kaW5nRXJyb3IoIkNhbm5vdCBwYXNzIG5vbi1zdHJpbmcgdG8gc3RkOjpzdHJpbmciKTt9aWYodmFsdWVJc09mVHlwZVN0cmluZyl7bGVuZ3RoPWxlbmd0aEJ5dGVzVVRGOCh2YWx1ZSk7fWVsc2Uge2xlbmd0aD12YWx1ZS5sZW5ndGg7fXZhciBiYXNlPV9tYWxsb2MoNCtsZW5ndGgrMSk7dmFyIHB0cj1iYXNlKzQ7SEVBUFUzMltiYXNlPj4yXT1sZW5ndGg7aWYodmFsdWVJc09mVHlwZVN0cmluZyl7c3RyaW5nVG9VVEY4KHZhbHVlLHB0cixsZW5ndGgrMSk7fWVsc2Uge2lmKHZhbHVlSXNPZlR5cGVTdHJpbmcpe2Zvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7dmFyIGNoYXJDb2RlPXZhbHVlLmNoYXJDb2RlQXQoaSk7aWYoY2hhckNvZGU+MjU1KXtfZnJlZShiYXNlKTt0aHJvd0JpbmRpbmdFcnJvcigiU3RyaW5nIGhhcyBVVEYtMTYgY29kZSB1bml0cyB0aGF0IGRvIG5vdCBmaXQgaW4gOCBiaXRzIik7fUhFQVBVOFtwdHIraV09Y2hhckNvZGU7fX1lbHNlIHtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe0hFQVBVOFtwdHIraV09dmFsdWVbaV07fX19aWYoZGVzdHJ1Y3RvcnMhPT1udWxsKXtkZXN0cnVjdG9ycy5wdXNoKF9mcmVlLGJhc2UpO31yZXR1cm4gYmFzZX0sYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpyZWFkUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb24ocHRyKXtfZnJlZShwdHIpO319KTt9O3ZhciBVVEYxNkRlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXIoInV0Zi0xNmxlIik6dW5kZWZpbmVkO3ZhciBVVEYxNlRvU3RyaW5nPShwdHIsbWF4Qnl0ZXNUb1JlYWQpPT57dmFyIGVuZFB0cj1wdHI7dmFyIGlkeD1lbmRQdHI+PjE7dmFyIG1heElkeD1pZHgrbWF4Qnl0ZXNUb1JlYWQvMjt3aGlsZSghKGlkeD49bWF4SWR4KSYmSEVBUFUxNltpZHhdKSsraWR4O2VuZFB0cj1pZHg8PDE7aWYoZW5kUHRyLXB0cj4zMiYmVVRGMTZEZWNvZGVyKXJldHVybiBVVEYxNkRlY29kZXIuZGVjb2RlKEhFQVBVOC5zdWJhcnJheShwdHIsZW5kUHRyKSk7dmFyIHN0cj0iIjtmb3IodmFyIGk9MDshKGk+PW1heEJ5dGVzVG9SZWFkLzIpOysraSl7dmFyIGNvZGVVbml0PUhFQVAxNltwdHIraSoyPj4xXTtpZihjb2RlVW5pdD09MClicmVhaztzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVVuaXQpO31yZXR1cm4gc3RyfTt2YXIgc3RyaW5nVG9VVEYxNj0oc3RyLG91dFB0cixtYXhCeXRlc1RvV3JpdGUpPT57bWF4Qnl0ZXNUb1dyaXRlPz89MjE0NzQ4MzY0NztpZihtYXhCeXRlc1RvV3JpdGU8MilyZXR1cm4gMDttYXhCeXRlc1RvV3JpdGUtPTI7dmFyIHN0YXJ0UHRyPW91dFB0cjt2YXIgbnVtQ2hhcnNUb1dyaXRlPW1heEJ5dGVzVG9Xcml0ZTxzdHIubGVuZ3RoKjI/bWF4Qnl0ZXNUb1dyaXRlLzI6c3RyLmxlbmd0aDtmb3IodmFyIGk9MDtpPG51bUNoYXJzVG9Xcml0ZTsrK2kpe3ZhciBjb2RlVW5pdD1zdHIuY2hhckNvZGVBdChpKTtIRUFQMTZbb3V0UHRyPj4xXT1jb2RlVW5pdDtvdXRQdHIrPTI7fUhFQVAxNltvdXRQdHI+PjFdPTA7cmV0dXJuIG91dFB0ci1zdGFydFB0cn07dmFyIGxlbmd0aEJ5dGVzVVRGMTY9c3RyPT5zdHIubGVuZ3RoKjI7dmFyIFVURjMyVG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9Pnt2YXIgaT0wO3ZhciBzdHI9IiI7d2hpbGUoIShpPj1tYXhCeXRlc1RvUmVhZC80KSl7dmFyIHV0ZjMyPUhFQVAzMltwdHIraSo0Pj4yXTtpZih1dGYzMj09MClicmVhazsrK2k7aWYodXRmMzI+PTY1NTM2KXt2YXIgY2g9dXRmMzItNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKTt9ZWxzZSB7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHV0ZjMyKTt9fXJldHVybiBzdHJ9O3ZhciBzdHJpbmdUb1VURjMyPShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PnttYXhCeXRlc1RvV3JpdGU/Pz0yMTQ3NDgzNjQ3O2lmKG1heEJ5dGVzVG9Xcml0ZTw0KXJldHVybiAwO3ZhciBzdGFydFB0cj1vdXRQdHI7dmFyIGVuZFB0cj1zdGFydFB0cittYXhCeXRlc1RvV3JpdGUtNDtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7aWYoY29kZVVuaXQ+PTU1Mjk2JiZjb2RlVW5pdDw9NTczNDMpe3ZhciB0cmFpbFN1cnJvZ2F0ZT1zdHIuY2hhckNvZGVBdCgrK2kpO2NvZGVVbml0PTY1NTM2KygoY29kZVVuaXQmMTAyMyk8PDEwKXx0cmFpbFN1cnJvZ2F0ZSYxMDIzO31IRUFQMzJbb3V0UHRyPj4yXT1jb2RlVW5pdDtvdXRQdHIrPTQ7aWYob3V0UHRyKzQ+ZW5kUHRyKWJyZWFrfUhFQVAzMltvdXRQdHI+PjJdPTA7cmV0dXJuIG91dFB0ci1zdGFydFB0cn07dmFyIGxlbmd0aEJ5dGVzVVRGMzI9c3RyPT57dmFyIGxlbj0wO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe3ZhciBjb2RlVW5pdD1zdHIuY2hhckNvZGVBdChpKTtpZihjb2RlVW5pdD49NTUyOTYmJmNvZGVVbml0PD01NzM0MykrK2k7bGVuKz00O31yZXR1cm4gbGVufTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfc3RkX3dzdHJpbmc9KHJhd1R5cGUsY2hhclNpemUsbmFtZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7dmFyIGRlY29kZVN0cmluZyxlbmNvZGVTdHJpbmcscmVhZENoYXJBdCxsZW5ndGhCeXRlc1VURjtpZihjaGFyU2l6ZT09PTIpe2RlY29kZVN0cmluZz1VVEYxNlRvU3RyaW5nO2VuY29kZVN0cmluZz1zdHJpbmdUb1VURjE2O2xlbmd0aEJ5dGVzVVRGPWxlbmd0aEJ5dGVzVVRGMTY7cmVhZENoYXJBdD1wb2ludGVyPT5IRUFQVTE2W3BvaW50ZXI+PjFdO31lbHNlIGlmKGNoYXJTaXplPT09NCl7ZGVjb2RlU3RyaW5nPVVURjMyVG9TdHJpbmc7ZW5jb2RlU3RyaW5nPXN0cmluZ1RvVVRGMzI7bGVuZ3RoQnl0ZXNVVEY9bGVuZ3RoQnl0ZXNVVEYzMjtyZWFkQ2hhckF0PXBvaW50ZXI9PkhFQVBVMzJbcG9pbnRlcj4+Ml07fXJlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTp2YWx1ZT0+e3ZhciBsZW5ndGg9SEVBUFUzMlt2YWx1ZT4+Ml07dmFyIHN0cjt2YXIgZGVjb2RlU3RhcnRQdHI9dmFsdWUrNDtmb3IodmFyIGk9MDtpPD1sZW5ndGg7KytpKXt2YXIgY3VycmVudEJ5dGVQdHI9dmFsdWUrNCtpKmNoYXJTaXplO2lmKGk9PWxlbmd0aHx8cmVhZENoYXJBdChjdXJyZW50Qnl0ZVB0cik9PTApe3ZhciBtYXhSZWFkQnl0ZXM9Y3VycmVudEJ5dGVQdHItZGVjb2RlU3RhcnRQdHI7dmFyIHN0cmluZ1NlZ21lbnQ9ZGVjb2RlU3RyaW5nKGRlY29kZVN0YXJ0UHRyLG1heFJlYWRCeXRlcyk7aWYoc3RyPT09dW5kZWZpbmVkKXtzdHI9c3RyaW5nU2VnbWVudDt9ZWxzZSB7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDApO3N0cis9c3RyaW5nU2VnbWVudDt9ZGVjb2RlU3RhcnRQdHI9Y3VycmVudEJ5dGVQdHIrY2hhclNpemU7fX1fZnJlZSh2YWx1ZSk7cmV0dXJuIHN0cn0sdG9XaXJlVHlwZTooZGVzdHJ1Y3RvcnMsdmFsdWUpPT57aWYoISh0eXBlb2YgdmFsdWU9PSJzdHJpbmciKSl7dGhyb3dCaW5kaW5nRXJyb3IoYENhbm5vdCBwYXNzIG5vbi1zdHJpbmcgdG8gQysrIHN0cmluZyB0eXBlICR7bmFtZX1gKTt9dmFyIGxlbmd0aD1sZW5ndGhCeXRlc1VURih2YWx1ZSk7dmFyIHB0cj1fbWFsbG9jKDQrbGVuZ3RoK2NoYXJTaXplKTtIRUFQVTMyW3B0cj4+Ml09bGVuZ3RoL2NoYXJTaXplO2VuY29kZVN0cmluZyh2YWx1ZSxwdHIrNCxsZW5ndGgrY2hhclNpemUpO2lmKGRlc3RydWN0b3JzIT09bnVsbCl7ZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSxwdHIpO31yZXR1cm4gcHRyfSxhcmdQYWNrQWR2YW5jZTpHZW5lcmljV2lyZVR5cGVTaXplLHJlYWRWYWx1ZUZyb21Qb2ludGVyOnJlYWRQb2ludGVyLGRlc3RydWN0b3JGdW5jdGlvbihwdHIpe19mcmVlKHB0cik7fX0pO307dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3ZvaWQ9KHJhd1R5cGUsbmFtZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse2lzVm9pZDp0cnVlLG5hbWUsYXJnUGFja0FkdmFuY2U6MCxmcm9tV2lyZVR5cGU6KCk9PnVuZGVmaW5lZCx0b1dpcmVUeXBlOihkZXN0cnVjdG9ycyxvKT0+dW5kZWZpbmVkfSk7fTt2YXIgZ2V0SGVhcE1heD0oKT0+MjE0NzQ4MzY0ODt2YXIgYWxpZ25NZW1vcnk9KHNpemUsYWxpZ25tZW50KT0+TWF0aC5jZWlsKHNpemUvYWxpZ25tZW50KSphbGlnbm1lbnQ7dmFyIGdyb3dNZW1vcnk9c2l6ZT0+e3ZhciBiPXdhc21NZW1vcnkuYnVmZmVyO3ZhciBwYWdlcz0oc2l6ZS1iLmJ5dGVMZW5ndGgrNjU1MzUpLzY1NTM2fDA7dHJ5e3dhc21NZW1vcnkuZ3JvdyhwYWdlcyk7dXBkYXRlTWVtb3J5Vmlld3MoKTtyZXR1cm4gMX1jYXRjaChlKXt9fTt2YXIgX2Vtc2NyaXB0ZW5fcmVzaXplX2hlYXA9cmVxdWVzdGVkU2l6ZT0+e3ZhciBvbGRTaXplPUhFQVBVOC5sZW5ndGg7cmVxdWVzdGVkU2l6ZT4+Pj0wO3ZhciBtYXhIZWFwU2l6ZT1nZXRIZWFwTWF4KCk7aWYocmVxdWVzdGVkU2l6ZT5tYXhIZWFwU2l6ZSl7cmV0dXJuIGZhbHNlfWZvcih2YXIgY3V0RG93bj0xO2N1dERvd248PTQ7Y3V0RG93bio9Mil7dmFyIG92ZXJHcm93bkhlYXBTaXplPW9sZFNpemUqKDErLjIvY3V0RG93bik7b3Zlckdyb3duSGVhcFNpemU9TWF0aC5taW4ob3Zlckdyb3duSGVhcFNpemUscmVxdWVzdGVkU2l6ZSsxMDA2NjMyOTYpO3ZhciBuZXdTaXplPU1hdGgubWluKG1heEhlYXBTaXplLGFsaWduTWVtb3J5KE1hdGgubWF4KHJlcXVlc3RlZFNpemUsb3Zlckdyb3duSGVhcFNpemUpLDY1NTM2KSk7dmFyIHJlcGxhY2VtZW50PWdyb3dNZW1vcnkobmV3U2l6ZSk7aWYocmVwbGFjZW1lbnQpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9O2Zvcih2YXIgYmFzZTY0UmV2ZXJzZUxvb2t1cD1uZXcgVWludDhBcnJheSgxMjMpLGk9MjU7aT49MDstLWkpe2Jhc2U2NFJldmVyc2VMb29rdXBbNDgraV09NTIraTtiYXNlNjRSZXZlcnNlTG9va3VwWzY1K2ldPWk7YmFzZTY0UmV2ZXJzZUxvb2t1cFs5NytpXT0yNitpO31iYXNlNjRSZXZlcnNlTG9va3VwWzQzXT02MjtiYXNlNjRSZXZlcnNlTG9va3VwWzQ3XT02MztlbWJpbmRfaW5pdF9jaGFyQ29kZXMoKTtCaW5kaW5nRXJyb3I9TW9kdWxlWyJCaW5kaW5nRXJyb3IiXT1jbGFzcyBCaW5kaW5nRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihtZXNzYWdlKXtzdXBlcihtZXNzYWdlKTt0aGlzLm5hbWU9IkJpbmRpbmdFcnJvciI7fX07TW9kdWxlWyJJbnRlcm5hbEVycm9yIl09Y2xhc3MgSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKG1lc3NhZ2Upe3N1cGVyKG1lc3NhZ2UpO3RoaXMubmFtZT0iSW50ZXJuYWxFcnJvciI7fX07aW5pdF9lbXZhbCgpO3ZhciB3YXNtSW1wb3J0cz17ajpfX2Fib3J0X2pzLGU6X19lbWJpbmRfcmVnaXN0ZXJfYmlnaW50LGg6X19lbWJpbmRfcmVnaXN0ZXJfYm9vbCxmOl9fZW1iaW5kX3JlZ2lzdGVyX2VtdmFsLGQ6X19lbWJpbmRfcmVnaXN0ZXJfZmxvYXQsYjpfX2VtYmluZF9yZWdpc3Rlcl9pbnRlZ2VyLGE6X19lbWJpbmRfcmVnaXN0ZXJfbWVtb3J5X3ZpZXcsZzpfX2VtYmluZF9yZWdpc3Rlcl9zdGRfc3RyaW5nLGM6X19lbWJpbmRfcmVnaXN0ZXJfc3RkX3dzdHJpbmcsaTpfX2VtYmluZF9yZWdpc3Rlcl92b2lkLGs6X2Vtc2NyaXB0ZW5fcmVzaXplX2hlYXB9O3ZhciB3YXNtRXhwb3J0cz1hd2FpdCBjcmVhdGVXYXNtKCk7d2FzbUV4cG9ydHNbIm0iXTtNb2R1bGVbIl9zb3J0Il09d2FzbUV4cG9ydHNbIm4iXTt2YXIgX21hbGxvYz1Nb2R1bGVbIl9tYWxsb2MiXT13YXNtRXhwb3J0c1sibyJdO3ZhciBfZnJlZT1Nb2R1bGVbIl9mcmVlIl09d2FzbUV4cG9ydHNbInAiXTtmdW5jdGlvbiBydW4oKXtpZihydW5EZXBlbmRlbmNpZXM+MCl7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPXJ1bjtyZXR1cm59cHJlUnVuKCk7aWYocnVuRGVwZW5kZW5jaWVzPjApe2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW47cmV0dXJufWZ1bmN0aW9uIGRvUnVuKCl7TW9kdWxlWyJjYWxsZWRSdW4iXT10cnVlO2lmKEFCT1JUKXJldHVybjtpbml0UnVudGltZSgpO3JlYWR5UHJvbWlzZVJlc29sdmUoTW9kdWxlKTtNb2R1bGVbIm9uUnVudGltZUluaXRpYWxpemVkIl0/LigpO3Bvc3RSdW4oKTt9aWYoTW9kdWxlWyJzZXRTdGF0dXMiXSl7TW9kdWxlWyJzZXRTdGF0dXMiXSgiUnVubmluZy4uLiIpO3NldFRpbWVvdXQoKCk9PntzZXRUaW1lb3V0KCgpPT5Nb2R1bGVbInNldFN0YXR1cyJdKCIiKSwxKTtkb1J1bigpO30sMSk7fWVsc2Uge2RvUnVuKCk7fX1pZihNb2R1bGVbInByZUluaXQiXSl7aWYodHlwZW9mIE1vZHVsZVsicHJlSW5pdCJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicHJlSW5pdCJdPVtNb2R1bGVbInByZUluaXQiXV07d2hpbGUoTW9kdWxlWyJwcmVJbml0Il0ubGVuZ3RoPjApe01vZHVsZVsicHJlSW5pdCJdLnBvcCgpKCk7fX1ydW4oKTttb2R1bGVSdG49cmVhZHlQcm9taXNlOw0KDQoNCiAgICByZXR1cm4gbW9kdWxlUnRuOw0KICB9DQogICk7DQogIH0pKCk7CgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CiAgbGV0IHdhc21Nb2R1bGU7CiAgYXN5bmMgZnVuY3Rpb24gaW5pdFdhc20oKSB7CiAgICAgIHdhc21Nb2R1bGUgPSBhd2FpdCBsb2FkV2FzbSgpOwogIH0KICBsZXQgc29ydERhdGE7CiAgbGV0IHZpZXdQcm9qUHRyOwogIGxldCB0cmFuc2Zvcm1zUHRyOwogIGxldCB0cmFuc2Zvcm1JbmRpY2VzUHRyOwogIGxldCBwb3NpdGlvbnNQdHI7CiAgbGV0IGRlcHRoQnVmZmVyUHRyOwogIGxldCBkZXB0aEluZGV4UHRyOwogIGxldCBzdGFydHNQdHI7CiAgbGV0IGNvdW50c1B0cjsKICBsZXQgYWxsb2NhdGVkVmVydGV4Q291bnQgPSAwOwogIGxldCBhbGxvY2F0ZWRUcmFuc2Zvcm1Db3VudCA9IDA7CiAgbGV0IHZpZXdQcm9qID0gW107CiAgbGV0IGRpcnR5ID0gdHJ1ZTsKICBsZXQgbG9jayA9IGZhbHNlOwogIGxldCBhbGxvY2F0aW9uUGVuZGluZyA9IGZhbHNlOwogIGxldCBzb3J0aW5nID0gZmFsc2U7CiAgY29uc3QgYWxsb2NhdGVCdWZmZXJzID0gYXN5bmMgKCkgPT4gewogICAgICBpZiAobG9jaykgewogICAgICAgICAgYWxsb2NhdGlvblBlbmRpbmcgPSB0cnVlOwogICAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGxvY2sgPSB0cnVlOwogICAgICBhbGxvY2F0aW9uUGVuZGluZyA9IGZhbHNlOwogICAgICBpZiAoIXdhc21Nb2R1bGUpCiAgICAgICAgICBhd2FpdCBpbml0V2FzbSgpOwogICAgICBjb25zdCB0YXJnZXRBbGxvY2F0ZWRWZXJ0ZXhDb3VudCA9IE1hdGgucG93KDIsIE1hdGguY2VpbChNYXRoLmxvZzIoc29ydERhdGEudmVydGV4Q291bnQpKSk7CiAgICAgIGlmIChhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA8IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50KSB7CiAgICAgICAgICBpZiAoYWxsb2NhdGVkVmVydGV4Q291bnQgPiAwKSB7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh2aWV3UHJvalB0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh0cmFuc2Zvcm1JbmRpY2VzUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHBvc2l0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShkZXB0aEJ1ZmZlclB0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShkZXB0aEluZGV4UHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHN0YXJ0c1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShjb3VudHNQdHIpOwogICAgICAgICAgfQogICAgICAgICAgYWxsb2NhdGVkVmVydGV4Q291bnQgPSB0YXJnZXRBbGxvY2F0ZWRWZXJ0ZXhDb3VudDsKICAgICAgICAgIHZpZXdQcm9qUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDE2ICogNCk7CiAgICAgICAgICB0cmFuc2Zvcm1JbmRpY2VzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBwb3NpdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoMyAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBkZXB0aEJ1ZmZlclB0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyhhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgZGVwdGhJbmRleFB0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyhhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgc3RhcnRzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBjb3VudHNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgfQogICAgICBpZiAoYWxsb2NhdGVkVHJhbnNmb3JtQ291bnQgPCBzb3J0RGF0YS50cmFuc2Zvcm1zLmxlbmd0aCkgewogICAgICAgICAgaWYgKGFsbG9jYXRlZFRyYW5zZm9ybUNvdW50ID4gMCkgewogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUodHJhbnNmb3Jtc1B0cik7CiAgICAgICAgICB9CiAgICAgICAgICBhbGxvY2F0ZWRUcmFuc2Zvcm1Db3VudCA9IHNvcnREYXRhLnRyYW5zZm9ybXMubGVuZ3RoOwogICAgICAgICAgdHJhbnNmb3Jtc1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyhhbGxvY2F0ZWRUcmFuc2Zvcm1Db3VudCAqIDQpOwogICAgICB9CiAgICAgIGxvY2sgPSBmYWxzZTsKICAgICAgaWYgKGFsbG9jYXRpb25QZW5kaW5nKSB7CiAgICAgICAgICBhbGxvY2F0aW9uUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgYXdhaXQgYWxsb2NhdGVCdWZmZXJzKCk7CiAgICAgIH0KICB9OwogIGNvbnN0IHJ1blNvcnQgPSAoKSA9PiB7CiAgICAgIGlmIChsb2NrIHx8IGFsbG9jYXRpb25QZW5kaW5nIHx8ICF3YXNtTW9kdWxlKQogICAgICAgICAgcmV0dXJuOwogICAgICBsb2NrID0gdHJ1ZTsKICAgICAgd2FzbU1vZHVsZS5IRUFQRjMyLnNldChzb3J0RGF0YS5wb3NpdGlvbnMsIHBvc2l0aW9uc1B0ciAvIDQpOwogICAgICB3YXNtTW9kdWxlLkhFQVBGMzIuc2V0KHNvcnREYXRhLnRyYW5zZm9ybXMsIHRyYW5zZm9ybXNQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5IRUFQVTMyLnNldChzb3J0RGF0YS50cmFuc2Zvcm1JbmRpY2VzLCB0cmFuc2Zvcm1JbmRpY2VzUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuSEVBUEYzMi5zZXQobmV3IEZsb2F0MzJBcnJheSh2aWV3UHJvaiksIHZpZXdQcm9qUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuX3NvcnQodmlld1Byb2pQdHIsIHRyYW5zZm9ybXNQdHIsIHRyYW5zZm9ybUluZGljZXNQdHIsIHNvcnREYXRhLnZlcnRleENvdW50LCBwb3NpdGlvbnNQdHIsIGRlcHRoQnVmZmVyUHRyLCBkZXB0aEluZGV4UHRyLCBzdGFydHNQdHIsIGNvdW50c1B0cik7CiAgICAgIGNvbnN0IGRlcHRoSW5kZXggPSBuZXcgVWludDMyQXJyYXkod2FzbU1vZHVsZS5IRUFQVTMyLmJ1ZmZlciwgZGVwdGhJbmRleFB0ciwgc29ydERhdGEudmVydGV4Q291bnQpOwogICAgICBjb25zdCBkZXRhY2hlZERlcHRoSW5kZXggPSBuZXcgVWludDMyQXJyYXkoZGVwdGhJbmRleC5zbGljZSgpLmJ1ZmZlcik7CiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoeyBkZXB0aEluZGV4OiBkZXRhY2hlZERlcHRoSW5kZXggfSwgW2RldGFjaGVkRGVwdGhJbmRleC5idWZmZXJdKTsKICAgICAgbG9jayA9IGZhbHNlOwogICAgICBkaXJ0eSA9IGZhbHNlOwogIH07CiAgY29uc3QgdGhyb3R0bGVkU29ydCA9ICgpID0+IHsKICAgICAgaWYgKCFzb3J0aW5nKSB7CiAgICAgICAgICBzb3J0aW5nID0gdHJ1ZTsKICAgICAgICAgIGlmIChkaXJ0eSkKICAgICAgICAgICAgICBydW5Tb3J0KCk7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgICBzb3J0aW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgdGhyb3R0bGVkU29ydCgpOwogICAgICAgICAgfSk7CiAgICAgIH0KICB9OwogIHNlbGYub25tZXNzYWdlID0gKGUpID0+IHsKICAgICAgaWYgKGUuZGF0YS5zb3J0RGF0YSkgewogICAgICAgICAgLy9SZWNyZWF0aW5nIHRoZSB0eXBlZCBhcnJheXMgZXZlcnkgdGltZSwgd2lsbCBjYXVzZSBmaXJlZm94IHRvIGxlYWsgbWVtb3J5CiAgICAgICAgICBpZiAoIXNvcnREYXRhKSB7CiAgICAgICAgICAgICAgc29ydERhdGEgPSB7CiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uczogbmV3IEZsb2F0MzJBcnJheShlLmRhdGEuc29ydERhdGEucG9zaXRpb25zKSwKICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtczogbmV3IEZsb2F0MzJBcnJheShlLmRhdGEuc29ydERhdGEudHJhbnNmb3JtcyksCiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybUluZGljZXM6IG5ldyBVaW50MzJBcnJheShlLmRhdGEuc29ydERhdGEudHJhbnNmb3JtSW5kaWNlcyksCiAgICAgICAgICAgICAgICAgIHZlcnRleENvdW50OiBlLmRhdGEuc29ydERhdGEudmVydGV4Q291bnQsCiAgICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIHNvcnREYXRhLnBvc2l0aW9ucy5zZXQoZS5kYXRhLnNvcnREYXRhLnBvc2l0aW9ucyk7CiAgICAgICAgICAgICAgc29ydERhdGEudHJhbnNmb3Jtcy5zZXQoZS5kYXRhLnNvcnREYXRhLnRyYW5zZm9ybXMpOwogICAgICAgICAgICAgIHNvcnREYXRhLnRyYW5zZm9ybUluZGljZXMuc2V0KGUuZGF0YS5zb3J0RGF0YS50cmFuc2Zvcm1JbmRpY2VzKTsKICAgICAgICAgICAgICBzb3J0RGF0YS52ZXJ0ZXhDb3VudCA9IGUuZGF0YS5zb3J0RGF0YS52ZXJ0ZXhDb3VudDsKICAgICAgICAgIH0KICAgICAgICAgIGRpcnR5ID0gdHJ1ZTsKICAgICAgICAgIGFsbG9jYXRlQnVmZmVycygpOwogICAgICB9CiAgICAgIGlmIChlLmRhdGEudmlld1Byb2opIHsKICAgICAgICAgIGlmIChlLmRhdGEudmlld1Byb2ouZXZlcnkoKGl0ZW0pID0+IHZpZXdQcm9qLmluY2x1ZGVzKGl0ZW0pKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICB2aWV3UHJvaiA9IGUuZGF0YS52aWV3UHJvajsKICAgICAgICAgICAgICBkaXJ0eSA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgICB0aHJvdHRsZWRTb3J0KCk7CiAgICAgIH0KICB9OwoKfSkoKTsKCg==",null,!1);class N{constructor(t,F){this._scene=null,this._camera=null,this._started=!1,this._initialized=!1,this._renderer=t;const U=t.gl;this._program=U.createProgram(),this._passes=F||[];const l=U.createShader(U.VERTEX_SHADER);U.shaderSource(l,this._getVertexSource()),U.compileShader(l),U.getShaderParameter(l,U.COMPILE_STATUS)||console.error(U.getShaderInfoLog(l));const n=U.createShader(U.FRAGMENT_SHADER);U.shaderSource(n,this._getFragmentSource()),U.compileShader(n),U.getShaderParameter(n,U.COMPILE_STATUS)||console.error(U.getShaderInfoLog(n)),U.attachShader(this.program,l),U.attachShader(this.program,n),U.linkProgram(this.program),U.getProgramParameter(this.program,U.LINK_STATUS)||console.error(U.getProgramInfoLog(this.program)),this.resize=()=>{U.useProgram(this._program),this._resize()},this.initialize=()=>{console.assert(!this._initialized,"ShaderProgram already initialized"),U.useProgram(this._program),this._initialize();for(const t of this.passes)t.initialize(this);this._initialized=!0,this._started=!0},this.render=(t,F)=>{U.useProgram(this._program),this._scene===t&&this._camera===F||(this.dispose(),this._scene=t,this._camera=F,this.initialize());for(const t of this.passes)t.render();this._render()},this.dispose=()=>{if(this._initialized){U.useProgram(this._program);for(const t of this.passes)t.dispose();this._dispose(),this._scene=null,this._camera=null,this._initialized=!1}}}get renderer(){return this._renderer}get scene(){return this._scene}get camera(){return this._camera}get program(){return this._program}get passes(){return this._passes}get started(){return this._started}}var G=g("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIGxvYWRXYXNtID0gKCgpID0+IHsNCiAgICANCiAgICByZXR1cm4gKA0KICBhc3luYyBmdW5jdGlvbihtb2R1bGVBcmcgPSB7fSkgew0KICAgIHZhciBtb2R1bGVSdG47DQoNCiAgdmFyIE1vZHVsZT1tb2R1bGVBcmc7dmFyIHJlYWR5UHJvbWlzZVJlc29sdmUscmVhZHlQcm9taXNlUmVqZWN0O3ZhciByZWFkeVByb21pc2U9bmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e3JlYWR5UHJvbWlzZVJlc29sdmU9cmVzb2x2ZTtyZWFkeVByb21pc2VSZWplY3Q9cmVqZWN0O30pO3ZhciBtb2R1bGVPdmVycmlkZXM9T2JqZWN0LmFzc2lnbih7fSxNb2R1bGUpO3ZhciBzY3JpcHREaXJlY3Rvcnk9IiI7dmFyIHJlYWRCaW5hcnk7e3tzY3JpcHREaXJlY3Rvcnk9c2VsZi5sb2NhdGlvbi5ocmVmO31pZihzY3JpcHREaXJlY3Rvcnkuc3RhcnRzV2l0aCgiYmxvYjoiKSl7c2NyaXB0RGlyZWN0b3J5PSIiO31lbHNlIHtzY3JpcHREaXJlY3Rvcnk9c2NyaXB0RGlyZWN0b3J5LnNsaWNlKDAsc2NyaXB0RGlyZWN0b3J5LnJlcGxhY2UoL1s/I10uKi8sIiIpLmxhc3RJbmRleE9mKCIvIikrMSk7fXt7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX07fX19TW9kdWxlWyJwcmludCJdfHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9TW9kdWxlWyJwcmludEVyciJdfHxjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7T2JqZWN0LmFzc2lnbihNb2R1bGUsbW9kdWxlT3ZlcnJpZGVzKTttb2R1bGVPdmVycmlkZXM9bnVsbDtpZihNb2R1bGVbImFyZ3VtZW50cyJdKU1vZHVsZVsiYXJndW1lbnRzIl07aWYoTW9kdWxlWyJ0aGlzUHJvZ3JhbSJdKU1vZHVsZVsidGhpc1Byb2dyYW0iXTt2YXIgd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTt2YXIgd2FzbU1lbW9yeTt2YXIgQUJPUlQ9ZmFsc2U7dmFyIEhFQVA4LEhFQVBVOCxIRUFQMTYsSEVBUFUxNixIRUFQMzIsSEVBUFUzMixIRUFQRjMyLEhFQVA2NCxIRUFQVTY0LEhFQVBGNjQ7ZnVuY3Rpb24gdXBkYXRlTWVtb3J5Vmlld3MoKXt2YXIgYj13YXNtTWVtb3J5LmJ1ZmZlcjtNb2R1bGVbIkhFQVA4Il09SEVBUDg9bmV3IEludDhBcnJheShiKTtNb2R1bGVbIkhFQVAxNiJdPUhFQVAxNj1uZXcgSW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVBVOCJdPUhFQVBVOD1uZXcgVWludDhBcnJheShiKTtNb2R1bGVbIkhFQVBVMTYiXT1IRUFQVTE2PW5ldyBVaW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVAzMiJdPUhFQVAzMj1uZXcgSW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBVMzIiXT1IRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBGMzIiXT1IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7TW9kdWxlWyJIRUFQRjY0Il09SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUDY0Il09SEVBUDY0PW5ldyBCaWdJbnQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUFU2NCJdPUhFQVBVNjQ9bmV3IEJpZ1VpbnQ2NEFycmF5KGIpO31mdW5jdGlvbiBwcmVSdW4oKXtpZihNb2R1bGVbInByZVJ1biJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZVJ1biJdPVtNb2R1bGVbInByZVJ1biJdXTt3aGlsZShNb2R1bGVbInByZVJ1biJdLmxlbmd0aCl7YWRkT25QcmVSdW4oTW9kdWxlWyJwcmVSdW4iXS5zaGlmdCgpKTt9fWNhbGxSdW50aW1lQ2FsbGJhY2tzKG9uUHJlUnVucyk7fWZ1bmN0aW9uIGluaXRSdW50aW1lKCl7d2FzbUV4cG9ydHNbIm0iXSgpO31mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpO319Y2FsbFJ1bnRpbWVDYWxsYmFja3Mob25Qb3N0UnVucyk7fXZhciBydW5EZXBlbmRlbmNpZXM9MDt2YXIgZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7ZnVuY3Rpb24gYWRkUnVuRGVwZW5kZW5jeShpZCl7cnVuRGVwZW5kZW5jaWVzKys7TW9kdWxlWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0/LihydW5EZXBlbmRlbmNpZXMpO31mdW5jdGlvbiByZW1vdmVSdW5EZXBlbmRlbmN5KGlkKXtydW5EZXBlbmRlbmNpZXMtLTtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXT8uKHJ1bkRlcGVuZGVuY2llcyk7aWYocnVuRGVwZW5kZW5jaWVzPT0wKXtpZihkZXBlbmRlbmNpZXNGdWxmaWxsZWQpe3ZhciBjYWxsYmFjaz1kZXBlbmRlbmNpZXNGdWxmaWxsZWQ7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7Y2FsbGJhY2soKTt9fX1mdW5jdGlvbiBhYm9ydCh3aGF0KXtNb2R1bGVbIm9uQWJvcnQiXT8uKHdoYXQpO3doYXQ9IkFib3J0ZWQoIit3aGF0KyIpIjtlcnIod2hhdCk7QUJPUlQ9dHJ1ZTt3aGF0Kz0iLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLiI7dmFyIGU9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcih3aGF0KTtyZWFkeVByb21pc2VSZWplY3QoZSk7dGhyb3cgZX12YXIgd2FzbUJpbmFyeUZpbGU9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCxBR0Z6YlFFQUFBQUJXQTFnQkg5L2YzOEFZQU4vZjM4QVlBVi9mMzkvZndCZ0JuOS9mMzkvZndCZ0FYOEFZQUYvQVg5Z0FBQmdBMzkvZndGL1lBSi9md0JnQlg5L2YzNStBR0FDZlgwQmYyQUJmUUYvWUF0L2YzOS9mMzkvZjM5L2Z3QUNRd3NCWVFGaEFBRUJZUUZpQUFJQllRRmpBQUVCWVFGa0FBRUJZUUZsQUFrQllRRm1BQVFCWVFGbkFBZ0JZUUZvQUFBQllRRnBBQWdCWVFGcUFBWUJZUUZyQUFVREdCY0hCUW9FQmdRR0FRQUJCQXNGREFNREFnSUFBQWNIQlFRRkFYQUJFQkFGQndFQmdnS0FnQUlHQ0FGL0FVSFFuUVFMQnhrR0FXd0NBQUZ0QUE4QmJnQVlBVzhBRndGd0FCQUJjUUVBQ1JVQkFFRUJDdzhoRGhVVklBNGZHUnNlRGhvY0hSRU1BUUlLeEZFWGNRRUJmeUFDUlFSQUlBQW9BZ1FnQVNnQ0JFWVBDeUFBSUFGR0JFQkJBUThMQWtBZ0FDZ0NCQ0lDTFFBQUlnQkZJQUFnQVNnQ0JDSUJMUUFBSWdOSGNnMEFBMEFnQVMwQUFTRURJQUl0QUFFaUFFVU5BU0FCUVFGcUlRRWdBa0VCYWlFQ0lBQWdBMFlOQUFzTElBQWdBMFlMVHdFQ2YwSE1HU2dDQUNJQklBQkJCMnBCZUhFaUFtb2hBQUpBSUFKQkFDQUFJQUZORzBVRVFDQUFQd0JCRUhSTkRRRWdBQkFLRFFFTFFkQVpRVEEyQWdCQmZ3OExRY3daSUFBMkFnQWdBUXNPQUNBQUVCWWdBUkFXUVJCMGNnc0dBQ0FBRUJBTEtRQkJ5QjFCRHpZQ0FFSE1IVUVBTmdJQUVCRkJ6QjFCeEIwb0FnQTJBZ0JCeEIxQnlCMDJBZ0FMM0FzQkNIOENRQ0FBUlEwQUlBQkJDR3NpQXlBQVFRUnJLQUlBSWdKQmVIRWlBR29oQlFKQUlBSkJBWEVOQUNBQ1FRSnhSUTBCSUFNZ0F5Z0NBQ0lFYXlJRFFlUVpLQUlBU1EwQklBQWdCR29oQUFKQUFrQUNRRUhvR1NnQ0FDQURSd1JBSUFNb0Fnd2hBU0FFUWY4QlRRUkFJQUVnQXlnQ0NDSUNSdzBDUWRRWlFkUVpLQUlBUVg0Z0JFRURkbmR4TmdJQURBVUxJQU1vQWhnaEJ5QUJJQU5IQkVBZ0F5Z0NDQ0lDSUFFMkFnd2dBU0FDTmdJSURBUUxJQU1vQWhRaUFnUi9JQU5CRkdvRklBTW9BaEFpQWtVTkF5QURRUkJxQ3lFRUEwQWdCQ0VHSUFJaUFVRVVhaUVFSUFFb0FoUWlBZzBBSUFGQkVHb2hCQ0FCS0FJUUlnSU5BQXNnQmtFQU5nSUFEQU1MSUFVb0FnUWlBa0VEY1VFRFJ3MERRZHdaSUFBMkFnQWdCU0FDUVg1eE5nSUVJQU1nQUVFQmNqWUNCQ0FGSUFBMkFnQVBDeUFDSUFFMkFnd2dBU0FDTmdJSURBSUxRUUFoQVFzZ0IwVU5BQUpBSUFNb0Fod2lCRUVDZEVHRUhHb2lBaWdDQUNBRFJnUkFJQUlnQVRZQ0FDQUJEUUZCMkJsQjJCa29BZ0JCZmlBRWQzRTJBZ0FNQWdzQ1FDQURJQWNvQWhCR0JFQWdCeUFCTmdJUURBRUxJQWNnQVRZQ0ZBc2dBVVVOQVFzZ0FTQUhOZ0lZSUFNb0FoQWlBZ1JBSUFFZ0FqWUNFQ0FDSUFFMkFoZ0xJQU1vQWhRaUFrVU5BQ0FCSUFJMkFoUWdBaUFCTmdJWUN5QURJQVZQRFFBZ0JTZ0NCQ0lFUVFGeFJRMEFBa0FDUUFKQUFrQWdCRUVDY1VVRVFFSHNHU2dDQUNBRlJnUkFRZXdaSUFNMkFnQkI0QmxCNEJrb0FnQWdBR29pQURZQ0FDQURJQUJCQVhJMkFnUWdBMEhvR1NnQ0FFY05Ca0hjR1VFQU5nSUFRZWdaUVFBMkFnQVBDMEhvR1NnQ0FDSUhJQVZHQkVCQjZCa2dBellDQUVIY0dVSGNHU2dDQUNBQWFpSUFOZ0lBSUFNZ0FFRUJjallDQkNBQUlBTnFJQUEyQWdBUEN5QUVRWGh4SUFCcUlRQWdCU2dDRENFQklBUkIvd0ZOQkVBZ0JTZ0NDQ0lDSUFGR0JFQkIxQmxCMUJrb0FnQkJmaUFFUVFOMmQzRTJBZ0FNQlFzZ0FpQUJOZ0lNSUFFZ0FqWUNDQXdFQ3lBRktBSVlJUWdnQVNBRlJ3UkFJQVVvQWdnaUFpQUJOZ0lNSUFFZ0FqWUNDQXdEQ3lBRktBSVVJZ0lFZnlBRlFSUnFCU0FGS0FJUUlnSkZEUUlnQlVFUWFnc2hCQU5BSUFRaEJpQUNJZ0ZCRkdvaEJDQUJLQUlVSWdJTkFDQUJRUkJxSVFRZ0FTZ0NFQ0lDRFFBTElBWkJBRFlDQUF3Q0N5QUZJQVJCZm5FMkFnUWdBeUFBUVFGeU5nSUVJQUFnQTJvZ0FEWUNBQXdEQzBFQUlRRUxJQWhGRFFBQ1FDQUZLQUljSWdSQkFuUkJoQnhxSWdJb0FnQWdCVVlFUUNBQ0lBRTJBZ0FnQVEwQlFkZ1pRZGdaS0FJQVFYNGdCSGR4TmdJQURBSUxBa0FnQlNBSUtBSVFSZ1JBSUFnZ0FUWUNFQXdCQ3lBSUlBRTJBaFFMSUFGRkRRRUxJQUVnQ0RZQ0dDQUZLQUlRSWdJRVFDQUJJQUkyQWhBZ0FpQUJOZ0lZQ3lBRktBSVVJZ0pGRFFBZ0FTQUNOZ0lVSUFJZ0FUWUNHQXNnQXlBQVFRRnlOZ0lFSUFBZ0Eyb2dBRFlDQUNBRElBZEhEUUJCM0JrZ0FEWUNBQThMSUFCQi93Rk5CRUFnQUVGNGNVSDhHV29oQWdKL1FkUVpLQUlBSWdSQkFTQUFRUU4yZENJQWNVVUVRRUhVR1NBQUlBUnlOZ0lBSUFJTUFRc2dBaWdDQ0FzaEFDQUNJQU0yQWdnZ0FDQUROZ0lNSUFNZ0FqWUNEQ0FESUFBMkFnZ1BDMEVmSVFFZ0FFSC8vLzhIVFFSQUlBQkJKaUFBUVFoMlp5SUNhM1pCQVhFZ0FrRUJkR3RCUG1vaEFRc2dBeUFCTmdJY0lBTkNBRGNDRUNBQlFRSjBRWVFjYWlFRUFuOENRQUovUWRnWktBSUFJZ1pCQVNBQmRDSUNjVVVFUUVIWUdTQUNJQVp5TmdJQUlBUWdBellDQUVFWUlRRkJDQXdCQ3lBQVFSa2dBVUVCZG10QkFDQUJRUjlIRzNRaEFTQUVLQUlBSVFRRFFDQUVJZ0lvQWdSQmVIRWdBRVlOQWlBQlFSMTJJUVFnQVVFQmRDRUJJQUlnQkVFRWNXb2lCaWdDRUNJRURRQUxJQVlnQXpZQ0VFRVlJUUVnQWlFRVFRZ0xJUUFnQXlJQ0RBRUxJQUlvQWdnaUJDQUROZ0lNSUFJZ0F6WUNDRUVZSVFCQkNDRUJRUUFMSVFZZ0FTQURhaUFFTmdJQUlBTWdBallDRENBQUlBTnFJQVkyQWdCQjlCbEI5QmtvQWdCQkFXc2lBRUYvSUFBYk5nSUFDd3ZhQXdCQnlCQkJ5Z29RQ0VIVUVFSDVDVUVCUVFBUUIwSGdFRUcwQ1VFQlFZQi9RZjhBRUFGQitCQkJyUWxCQVVHQWYwSC9BQkFCUWV3UVFhc0pRUUZCQUVIL0FSQUJRWVFSUWY4SVFRSkJnSUIrUWYvL0FSQUJRWkFSUWZZSVFRSkJBRUgvL3dNUUFVR2NFVUdPQ1VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCcUJGQmhRbEJCRUVBUVg4UUFVRzBFVUdIQ2tFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCd0JGQi9nbEJCRUVBUVg4UUFVSE1FVUdaQ1VFSVFvQ0FnSUNBZ0lDQWdIOUMvLy8vLy8vLy8vLy9BQkFFUWRnUlFaZ0pRUWhDQUVKL0VBUkI1QkZCa2dsQkJCQURRZkFSUWNNS1FRZ1FBMEdBRTBHWkNoQUdRY2dUUVFSQmpBb1FBa0dRRkVFQ1FhVUtFQUpCM0JSQkJFRzBDaEFDUWFnVkVBVkJ4QlZCQUVHbURoQUFRZXdWUVFCQjZ3NFFBRUdVRmtFQlFjUU9FQUJCdkJaQkFrSHpDaEFBUWVRV1FRTkJrZ3NRQUVHTUYwRUVRYm9MRUFCQnRCZEJCVUhYQ3hBQVFkd1hRUVJCa0E4UUFFR0VHRUVGUWE0UEVBQkI3QlZCQUVHOURCQUFRWlFXUVFGQm5Bd1FBRUc4RmtFQ1FmOE1FQUJCNUJaQkEwSGREQkFBUVl3WFFRUkJoUTRRQUVHMEYwRUZRZU1ORUFCQnJCaEJDRUhDRFJBQVFkUVlRUWxCb0EwUUFFSDhHRUVHUWYwTEVBQkJwQmxCQjBIVkR4QUFDeUFBQWtBZ0FTQUFLQUlFUncwQUlBQW9BaHhCQVVZTkFDQUFJQUkyQWh3TEM1b0JBQ0FBUVFFNkFEVUNRQ0FDSUFBb0FnUkhEUUFnQUVFQk9nQTBBa0FnQUNnQ0VDSUNSUVJBSUFCQkFUWUNKQ0FBSUFNMkFoZ2dBQ0FCTmdJUUlBTkJBVWNOQWlBQUtBSXdRUUZHRFFFTUFnc2dBU0FDUmdSQUlBQW9BaGdpQWtFQ1JnUkFJQUFnQXpZQ0dDQURJUUlMSUFBb0FqQkJBVWNOQWlBQ1FRRkdEUUVNQWdzZ0FDQUFLQUlrUVFGcU5nSWtDeUFBUVFFNkFEWUxDM1lCQVg4Z0FDZ0NKQ0lEUlFSQUlBQWdBallDR0NBQUlBRTJBaEFnQUVFQk5nSWtJQUFnQUNnQ09EWUNGQThMQWtBQ1FDQUFLQUlVSUFBb0FqaEhEUUFnQUNnQ0VDQUJSdzBBSUFBb0FoaEJBa2NOQVNBQUlBSTJBaGdQQ3lBQVFRRTZBRFlnQUVFQ05nSVlJQUFnQTBFQmFqWUNKQXNMQWdBTGNnRUVmeUFBdkNJRVFmLy8vd054SVFFQ1FDQUVRUmQyUWY4QmNTSUNSUTBBSUFKQjhBQk5CRUFnQVVHQWdJQUVja0h4QUNBQ2EzWWhBUXdCQ3lBQ1FZMEJTd1JBUVlENEFTRURRUUFoQVF3QkN5QUNRUXAwUVlDQUIyc2hBd3NnQXlBRVFSQjJRWUNBQW5GeUlBRkJEWFp5QzlFbkFRdC9Jd0JCRUdzaUNpUUFBa0FDUUFKQUFrQUNRQUpBQWtBQ1FBSkFBa0FnQUVIMEFVMEVRRUhVR1NnQ0FDSUVRUkFnQUVFTGFrSDRBM0VnQUVFTFNSc2lCa0VEZGlJQWRpSUJRUU54QkVBQ1FDQUJRWDl6UVFGeElBQnFJZ0pCQTNRaUFVSDhHV29pQUNBQlFZUWFhaWdDQUNJQktBSUlJZ1ZHQkVCQjFCa2dCRUYrSUFKM2NUWUNBQXdCQ3lBRklBQTJBZ3dnQUNBRk5nSUlDeUFCUVFocUlRQWdBU0FDUVFOMElnSkJBM0kyQWdRZ0FTQUNhaUlCSUFFb0FnUkJBWEkyQWdRTUN3c2dCa0hjR1NnQ0FDSUlUUTBCSUFFRVFBSkFRUUlnQUhRaUFrRUFJQUpyY2lBQklBQjBjV2dpQVVFRGRDSUFRZndaYWlJQ0lBQkJoQnBxS0FJQUlnQW9BZ2dpQlVZRVFFSFVHU0FFUVg0Z0FYZHhJZ1EyQWdBTUFRc2dCU0FDTmdJTUlBSWdCVFlDQ0FzZ0FDQUdRUU55TmdJRUlBQWdCbW9pQnlBQlFRTjBJZ0VnQm1zaUJVRUJjallDQkNBQUlBRnFJQVUyQWdBZ0NBUkFJQWhCZUhGQi9CbHFJUUZCNkJrb0FnQWhBZ0ovSUFSQkFTQUlRUU4yZENJRGNVVUVRRUhVR1NBRElBUnlOZ0lBSUFFTUFRc2dBU2dDQ0FzaEF5QUJJQUkyQWdnZ0F5QUNOZ0lNSUFJZ0FUWUNEQ0FDSUFNMkFnZ0xJQUJCQ0dvaEFFSG9HU0FITmdJQVFkd1pJQVUyQWdBTUN3dEIyQmtvQWdBaUMwVU5BU0FMYUVFQ2RFR0VIR29vQWdBaUFpZ0NCRUY0Y1NBR2F5RURJQUloQVFOQUFrQWdBU2dDRUNJQVJRUkFJQUVvQWhRaUFFVU5BUXNnQUNnQ0JFRjRjU0FHYXlJQklBTWdBU0FEU1NJQkd5RURJQUFnQWlBQkd5RUNJQUFoQVF3QkN3c2dBaWdDR0NFSklBSWdBaWdDRENJQVJ3UkFJQUlvQWdnaUFTQUFOZ0lNSUFBZ0FUWUNDQXdLQ3lBQ0tBSVVJZ0VFZnlBQ1FSUnFCU0FDS0FJUUlnRkZEUU1nQWtFUWFnc2hCUU5BSUFVaEJ5QUJJZ0JCRkdvaEJTQUFLQUlVSWdFTkFDQUFRUkJxSVFVZ0FDZ0NFQ0lCRFFBTElBZEJBRFlDQUF3SkMwRi9JUVlnQUVHL2Ywc05BQ0FBUVF0cUlnRkJlSEVoQmtIWUdTZ0NBQ0lIUlEwQVFSOGhDRUVBSUFacklRTWdBRUgwLy84SFRRUkFJQVpCSmlBQlFRaDJaeUlBYTNaQkFYRWdBRUVCZEd0QlBtb2hDQXNDUUFKQUFrQWdDRUVDZEVHRUhHb29BZ0FpQVVVRVFFRUFJUUFNQVF0QkFDRUFJQVpCR1NBSVFRRjJhMEVBSUFoQkgwY2JkQ0VDQTBBQ1FDQUJLQUlFUVhoeElBWnJJZ1FnQTA4TkFDQUJJUVVnQkNJRERRQkJBQ0VESUFFaEFBd0RDeUFBSUFFb0FoUWlCQ0FFSUFFZ0FrRWRka0VFY1dvb0FoQWlBVVliSUFBZ0JCc2hBQ0FDUVFGMElRSWdBUTBBQ3dzZ0FDQUZja1VFUUVFQUlRVkJBaUFJZENJQVFRQWdBR3R5SUFkeElnQkZEUU1nQUdoQkFuUkJoQnhxS0FJQUlRQUxJQUJGRFFFTEEwQWdBQ2dDQkVGNGNTQUdheUlDSUFOSklRRWdBaUFESUFFYklRTWdBQ0FGSUFFYklRVWdBQ2dDRUNJQkJIOGdBUVVnQUNnQ0ZBc2lBQTBBQ3dzZ0JVVU5BQ0FEUWR3WktBSUFJQVpyVHcwQUlBVW9BaGdoQ0NBRklBVW9BZ3dpQUVjRVFDQUZLQUlJSWdFZ0FEWUNEQ0FBSUFFMkFnZ01DQXNnQlNnQ0ZDSUJCSDhnQlVFVWFnVWdCU2dDRUNJQlJRMERJQVZCRUdvTElRSURRQ0FDSVFRZ0FTSUFRUlJxSVFJZ0FDZ0NGQ0lCRFFBZ0FFRVFhaUVDSUFBb0FoQWlBUTBBQ3lBRVFRQTJBZ0FNQndzZ0JrSGNHU2dDQUNJRlRRUkFRZWdaS0FJQUlRQUNRQ0FGSUFacklnRkJFRThFUUNBQUlBWnFJZ0lnQVVFQmNqWUNCQ0FBSUFWcUlBRTJBZ0FnQUNBR1FRTnlOZ0lFREFFTElBQWdCVUVEY2pZQ0JDQUFJQVZxSWdFZ0FTZ0NCRUVCY2pZQ0JFRUFJUUpCQUNFQkMwSGNHU0FCTmdJQVFlZ1pJQUkyQWdBZ0FFRUlhaUVBREFrTElBWkI0QmtvQWdBaUFra0VRRUhnR1NBQ0lBWnJJZ0UyQWdCQjdCbEI3QmtvQWdBaUFDQUdhaUlDTmdJQUlBSWdBVUVCY2pZQ0JDQUFJQVpCQTNJMkFnUWdBRUVJYWlFQURBa0xRUUFoQUNBR1FTOXFJZ01DZjBHc0hTZ0NBQVJBUWJRZEtBSUFEQUVMUWJnZFFuODNBZ0JCc0IxQ2dLQ0FnSUNBQkRjQ0FFR3NIU0FLUVF4cVFYQnhRZGlxMWFvRmN6WUNBRUhBSFVFQU5nSUFRWkFkUVFBMkFnQkJnQ0FMSWdGcUlnUkJBQ0FCYXlJSGNTSUJJQVpORFFoQmpCMG9BZ0FpQlFSQVFZUWRLQUlBSWdnZ0FXb2lDU0FJVFNBRklBbEpjZzBKQ3dKQVFaQWRMUUFBUVFSeFJRUkFBa0FDUUFKQUFrQkI3QmtvQWdBaUJRUkFRWlFkSVFBRFFDQUFLQUlBSWdnZ0JVMEVRQ0FGSUFnZ0FDZ0NCR3BKRFFNTElBQW9BZ2dpQUEwQUN3dEJBQkFNSWdKQmYwWU5BeUFCSVFSQnNCMG9BZ0FpQUVFQmF5SUZJQUp4QkVBZ0FTQUNheUFDSUFWcVFRQWdBR3R4YWlFRUN5QUVJQVpORFFOQmpCMG9BZ0FpQUFSQVFZUWRLQUlBSWdVZ0JHb2lCeUFGVFNBQUlBZEpjZzBFQ3lBRUVBd2lBQ0FDUncwQkRBVUxJQVFnQW1zZ0IzRWlCQkFNSWdJZ0FDZ0NBQ0FBS0FJRWFrWU5BU0FDSVFBTElBQkJmMFlOQVNBR1FUQnFJQVJOQkVBZ0FDRUNEQVFMUWJRZEtBSUFJZ0lnQXlBRWEycEJBQ0FDYTNFaUFoQU1RWDlHRFFFZ0FpQUVhaUVFSUFBaEFnd0RDeUFDUVg5SERRSUxRWkFkUVpBZEtBSUFRUVJ5TmdJQUN5QUJFQXdpQWtGL1JrRUFFQXdpQUVGL1JuSWdBQ0FDVFhJTkJTQUFJQUpySWdRZ0JrRW9hazBOQlF0QmhCMUJoQjBvQWdBZ0JHb2lBRFlDQUVHSUhTZ0NBQ0FBU1FSQVFZZ2RJQUEyQWdBTEFrQkI3QmtvQWdBaUF3UkFRWlFkSVFBRFFDQUNJQUFvQWdBaUFTQUFLQUlFSWdWcVJnMENJQUFvQWdnaUFBMEFDd3dFQzBIa0dTZ0NBQ0lBUVFBZ0FDQUNUUnRGQkVCQjVCa2dBallDQUF0QkFDRUFRWmdkSUFRMkFnQkJsQjBnQWpZQ0FFSDBHVUYvTmdJQVFmZ1pRYXdkS0FJQU5nSUFRYUFkUVFBMkFnQURRQ0FBUVFOMElnRkJoQnBxSUFGQi9CbHFJZ1UyQWdBZ0FVR0lHbW9nQlRZQ0FDQUFRUUZxSWdCQklFY05BQXRCNEJrZ0JFRW9heUlBUVhnZ0FtdEJCM0VpQVdzaUJUWUNBRUhzR1NBQklBSnFJZ0UyQWdBZ0FTQUZRUUZ5TmdJRUlBQWdBbXBCS0RZQ0JFSHdHVUc4SFNnQ0FEWUNBQXdFQ3lBQ0lBTk5JQUVnQTB0eURRSWdBQ2dDREVFSWNRMENJQUFnQkNBRmFqWUNCRUhzR1NBRFFYZ2dBMnRCQjNFaUFHb2lBVFlDQUVIZ0dVSGdHU2dDQUNBRWFpSUNJQUJySWdBMkFnQWdBU0FBUVFGeU5nSUVJQUlnQTJwQktEWUNCRUh3R1VHOEhTZ0NBRFlDQUF3REMwRUFJUUFNQmd0QkFDRUFEQVFMUWVRWktBSUFJQUpMQkVCQjVCa2dBallDQUFzZ0FpQUVhaUVGUVpRZElRQUNRQU5BSUFVZ0FDZ0NBQ0lCUndSQUlBQW9BZ2dpQUEwQkRBSUxDeUFBTFFBTVFRaHhSUTBEQzBHVUhTRUFBMEFDUUNBQUtBSUFJZ0VnQTAwRVFDQURJQUVnQUNnQ0JHb2lCVWtOQVFzZ0FDZ0NDQ0VBREFFTEMwSGdHU0FFUVNocklnQkJlQ0FDYTBFSGNTSUJheUlITmdJQVFld1pJQUVnQW1vaUFUWUNBQ0FCSUFkQkFYSTJBZ1FnQUNBQ2FrRW9OZ0lFUWZBWlFid2RLQUlBTmdJQUlBTWdCVUVuSUFWclFRZHhha0V2YXlJQUlBQWdBMEVRYWtrYklnRkJHellDQkNBQlFad2RLUUlBTndJUUlBRkJsQjBwQWdBM0FnaEJuQjBnQVVFSWFqWUNBRUdZSFNBRU5nSUFRWlFkSUFJMkFnQkJvQjFCQURZQ0FDQUJRUmhxSVFBRFFDQUFRUWMyQWdRZ0FFRUlhaUFBUVFScUlRQWdCVWtOQUFzZ0FTQURSZzBBSUFFZ0FTZ0NCRUYrY1RZQ0JDQURJQUVnQTJzaUFrRUJjallDQkNBQklBSTJBZ0FDZnlBQ1FmOEJUUVJBSUFKQmVIRkIvQmxxSVFBQ2YwSFVHU2dDQUNJQlFRRWdBa0VEZG5RaUFuRkZCRUJCMUJrZ0FTQUNjallDQUNBQURBRUxJQUFvQWdnTElRRWdBQ0FETmdJSUlBRWdBellDREVFTUlRSkJDQXdCQzBFZklRQWdBa0gvLy84SFRRUkFJQUpCSmlBQ1FRaDJaeUlBYTNaQkFYRWdBRUVCZEd0QlBtb2hBQXNnQXlBQU5nSWNJQU5DQURjQ0VDQUFRUUowUVlRY2FpRUJBa0FDUUVIWUdTZ0NBQ0lGUVFFZ0FIUWlCSEZGQkVCQjJCa2dCQ0FGY2pZQ0FDQUJJQU0yQWdBTUFRc2dBa0VaSUFCQkFYWnJRUUFnQUVFZlJ4dDBJUUFnQVNnQ0FDRUZBMEFnQlNJQktBSUVRWGh4SUFKR0RRSWdBRUVkZGlFRklBQkJBWFFoQUNBQklBVkJCSEZxSWdRb0FoQWlCUTBBQ3lBRUlBTTJBaEFMSUFNZ0FUWUNHRUVJSVFJZ0F5SUJJUUJCREF3QkN5QUJLQUlJSWdBZ0F6WUNEQ0FCSUFNMkFnZ2dBeUFBTmdJSVFRQWhBRUVZSVFKQkRBc2dBMm9nQVRZQ0FDQUNJQU5xSUFBMkFnQUxRZUFaS0FJQUlnQWdCazBOQUVIZ0dTQUFJQVpySWdFMkFnQkI3QmxCN0Jrb0FnQWlBQ0FHYWlJQ05nSUFJQUlnQVVFQmNqWUNCQ0FBSUFaQkEzSTJBZ1FnQUVFSWFpRUFEQVFMUWRBWlFUQTJBZ0JCQUNFQURBTUxJQUFnQWpZQ0FDQUFJQUFvQWdRZ0JHbzJBZ1FnQWtGNElBSnJRUWR4YWlJSUlBWkJBM0kyQWdRZ0FVRjRJQUZyUVFkeGFpSUVJQVlnQ0dvaUEyc2hCd0pBUWV3WktBSUFJQVJHQkVCQjdCa2dBellDQUVIZ0dVSGdHU2dDQUNBSGFpSUFOZ0lBSUFNZ0FFRUJjallDQkF3QkMwSG9HU2dDQUNBRVJnUkFRZWdaSUFNMkFnQkIzQmxCM0Jrb0FnQWdCMm9pQURZQ0FDQURJQUJCQVhJMkFnUWdBQ0FEYWlBQU5nSUFEQUVMSUFRb0FnUWlBRUVEY1VFQlJnUkFJQUJCZUhFaENTQUVLQUlNSVFJQ1FDQUFRZjhCVFFSQUlBUW9BZ2dpQVNBQ1JnUkFRZFFaUWRRWktBSUFRWDRnQUVFRGRuZHhOZ0lBREFJTElBRWdBallDRENBQ0lBRTJBZ2dNQVFzZ0JDZ0NHQ0VHQWtBZ0FpQUVSd1JBSUFRb0FnZ2lBQ0FDTmdJTUlBSWdBRFlDQ0F3QkN3SkFJQVFvQWhRaUFBUi9JQVJCRkdvRklBUW9BaEFpQUVVTkFTQUVRUkJxQ3lFQkEwQWdBU0VGSUFBaUFrRVVhaUVCSUFBb0FoUWlBQTBBSUFKQkVHb2hBU0FDS0FJUUlnQU5BQXNnQlVFQU5nSUFEQUVMUVFBaEFnc2dCa1VOQUFKQUlBUW9BaHdpQUVFQ2RFR0VIR29pQVNnQ0FDQUVSZ1JBSUFFZ0FqWUNBQ0FDRFFGQjJCbEIyQmtvQWdCQmZpQUFkM0UyQWdBTUFnc0NRQ0FFSUFZb0FoQkdCRUFnQmlBQ05nSVFEQUVMSUFZZ0FqWUNGQXNnQWtVTkFRc2dBaUFHTmdJWUlBUW9BaEFpQUFSQUlBSWdBRFlDRUNBQUlBSTJBaGdMSUFRb0FoUWlBRVVOQUNBQ0lBQTJBaFFnQUNBQ05nSVlDeUFISUFscUlRY2dCQ0FKYWlJRUtBSUVJUUFMSUFRZ0FFRitjVFlDQkNBRElBZEJBWEkyQWdRZ0F5QUhhaUFITmdJQUlBZEIvd0ZOQkVBZ0IwRjRjVUg4R1dvaEFBSi9RZFFaS0FJQUlnRkJBU0FIUVFOMmRDSUNjVVVFUUVIVUdTQUJJQUp5TmdJQUlBQU1BUXNnQUNnQ0NBc2hBU0FBSUFNMkFnZ2dBU0FETmdJTUlBTWdBRFlDRENBRElBRTJBZ2dNQVF0Qkh5RUNJQWRCLy8vL0IwMEVRQ0FIUVNZZ0IwRUlkbWNpQUd0MlFRRnhJQUJCQVhSclFUNXFJUUlMSUFNZ0FqWUNIQ0FEUWdBM0FoQWdBa0VDZEVHRUhHb2hBQUpBQWtCQjJCa29BZ0FpQVVFQklBSjBJZ1Z4UlFSQVFkZ1pJQUVnQlhJMkFnQWdBQ0FETmdJQURBRUxJQWRCR1NBQ1FRRjJhMEVBSUFKQkgwY2JkQ0VDSUFBb0FnQWhBUU5BSUFFaUFDZ0NCRUY0Y1NBSFJnMENJQUpCSFhZaEFTQUNRUUYwSVFJZ0FDQUJRUVJ4YWlJRktBSVFJZ0VOQUFzZ0JTQUROZ0lRQ3lBRElBQTJBaGdnQXlBRE5nSU1JQU1nQXpZQ0NBd0JDeUFBS0FJSUlnRWdBellDRENBQUlBTTJBZ2dnQTBFQU5nSVlJQU1nQURZQ0RDQURJQUUyQWdnTElBaEJDR29oQUF3Q0N3SkFJQWhGRFFBQ1FDQUZLQUljSWdGQkFuUkJoQnhxSWdJb0FnQWdCVVlFUUNBQ0lBQTJBZ0FnQUEwQlFkZ1pJQWRCZmlBQmQzRWlCellDQUF3Q0N3SkFJQVVnQ0NnQ0VFWUVRQ0FJSUFBMkFoQU1BUXNnQ0NBQU5nSVVDeUFBUlEwQkN5QUFJQWcyQWhnZ0JTZ0NFQ0lCQkVBZ0FDQUJOZ0lRSUFFZ0FEWUNHQXNnQlNnQ0ZDSUJSUTBBSUFBZ0FUWUNGQ0FCSUFBMkFoZ0xBa0FnQTBFUFRRUkFJQVVnQXlBR2FpSUFRUU55TmdJRUlBQWdCV29pQUNBQUtBSUVRUUZ5TmdJRURBRUxJQVVnQmtFRGNqWUNCQ0FGSUFacUlnUWdBMEVCY2pZQ0JDQURJQVJxSUFNMkFnQWdBMEgvQVUwRVFDQURRWGh4UWZ3WmFpRUFBbjlCMUJrb0FnQWlBVUVCSUFOQkEzWjBJZ0p4UlFSQVFkUVpJQUVnQW5JMkFnQWdBQXdCQ3lBQUtBSUlDeUVCSUFBZ0JEWUNDQ0FCSUFRMkFnd2dCQ0FBTmdJTUlBUWdBVFlDQ0F3QkMwRWZJUUFnQTBILy8vOEhUUVJBSUFOQkppQURRUWgyWnlJQWEzWkJBWEVnQUVFQmRHdEJQbW9oQUFzZ0JDQUFOZ0ljSUFSQ0FEY0NFQ0FBUVFKMFFZUWNhaUVCQWtBQ1FDQUhRUUVnQUhRaUFuRkZCRUJCMkJrZ0FpQUhjallDQUNBQklBUTJBZ0FnQkNBQk5nSVlEQUVMSUFOQkdTQUFRUUYyYTBFQUlBQkJIMGNiZENFQUlBRW9BZ0FoQVFOQUlBRWlBaWdDQkVGNGNTQURSZzBDSUFCQkhYWWhBU0FBUVFGMElRQWdBaUFCUVFSeGFpSUhLQUlRSWdFTkFBc2dCeUFFTmdJUUlBUWdBallDR0FzZ0JDQUVOZ0lNSUFRZ0JEWUNDQXdCQ3lBQ0tBSUlJZ0FnQkRZQ0RDQUNJQVEyQWdnZ0JFRUFOZ0lZSUFRZ0FqWUNEQ0FFSUFBMkFnZ0xJQVZCQ0dvaEFBd0JDd0pBSUFsRkRRQUNRQ0FDS0FJY0lnRkJBblJCaEJ4cUlnVW9BZ0FnQWtZRVFDQUZJQUEyQWdBZ0FBMEJRZGdaSUF0QmZpQUJkM0UyQWdBTUFnc0NRQ0FDSUFrb0FoQkdCRUFnQ1NBQU5nSVFEQUVMSUFrZ0FEWUNGQXNnQUVVTkFRc2dBQ0FKTmdJWUlBSW9BaEFpQVFSQUlBQWdBVFlDRUNBQklBQTJBaGdMSUFJb0FoUWlBVVVOQUNBQUlBRTJBaFFnQVNBQU5nSVlDd0pBSUFOQkQwMEVRQ0FDSUFNZ0Jtb2lBRUVEY2pZQ0JDQUFJQUpxSWdBZ0FDZ0NCRUVCY2pZQ0JBd0JDeUFDSUFaQkEzSTJBZ1FnQWlBR2FpSUZJQU5CQVhJMkFnUWdBeUFGYWlBRE5nSUFJQWdFUUNBSVFYaHhRZndaYWlFQVFlZ1pLQUlBSVFFQ2YwRUJJQWhCQTNaMElnY2dCSEZGQkVCQjFCa2dCQ0FIY2pZQ0FDQUFEQUVMSUFBb0FnZ0xJUVFnQUNBQk5nSUlJQVFnQVRZQ0RDQUJJQUEyQWd3Z0FTQUVOZ0lJQzBIb0dTQUZOZ0lBUWR3WklBTTJBZ0FMSUFKQkNHb2hBQXNnQ2tFUWFpUUFJQUFMcVFzQ0MzOEpmU01BUWFBQmF5SUxKQUFnQzBFd2FrRUFRU1Q4Q3dBRFFDQUJJQTFIQkVBZ0FpQU5RUU5zSWd4QkFtcEJBblFpRG1vcUFnQWhGeUFDSUF4QkFXcEJBblFpRDJvcUFnQWhHQ0FJSUF4QkFuUWlFR29nQWlBUWFpb0NBQ0laT0FJQUlBZ2dEMm9nR0RnQ0FDQUlJQTVxSUJjNEFnQWdCeUFOUVFWMGFpSU1JQmc0QWdRZ0RDQVpPQUlBSUF3Z0Z6Z0NDQ0FNUVFBMkFnd0NRQ0FBUlFSQUlBWWdEV290QUFCRkRRRUxJQXhCZ0lDQUNEWUNEQXNnQnlBTlFRVjBhaUlSSUFVZ0RVRUNkQ0lNUVFGeUloSnFMUUFBUVFoMElBVWdER290QUFCeUlBVWdERUVDY2lJVGFpMEFBRUVRZEhJZ0JTQU1RUU55SWd4cUxRQUFRUmgwY2pZQ0hDQUxJQU1nRWtFQ2RDSVNhaW9DQUNJWE9BS1FBU0FMSUFNZ0UwRUNkQ0lUYWlvQ0FDSVlPQUtVQVNBTElBTWdERUVDZENJVWFpb0NBQ0laT0FLWUFTQUxJQU1nRFVFRWRDSVZhaW9DQUl3aUdqZ0NuQUVnQzBIZ0FHb2lEQ0FMS2dLWUFTSVdRd0FBQU1DVUlCYVVJQXNxQXBRQkloWkRBQUFBd0pRZ0ZwUkRBQUNBUDVLU09BSUFJQXdnQ3lvQ2tBRWlGaUFXa2lBTEtnS1VBWlFnQ3lvQ21BRWlGaUFXa2lBTEtnS2NBWlNUT0FJRUlBd2dDeW9Da0FFaUZpQVdraUFMS2dLWUFaUWdDeW9DbEFFaUZpQVdraUFMS2dLY0FaU1NPQUlJSUF3Z0N5b0NrQUVpRmlBV2tpQUxLZ0tVQVpRZ0N5b0NtQUVpRmlBV2tpQUxLZ0tjQVpTU09BSU1JQXdnQ3lvQ21BRWlGa01BQUFEQWxDQVdsQ0FMS2dLUUFTSVdRd0FBQU1DVUlCYVVRd0FBZ0QrU2tqZ0NFQ0FNSUFzcUFwUUJJaFlnRnBJZ0N5b0NtQUdVSUFzcUFwQUJJaFlnRnBJZ0N5b0NuQUdVa3pnQ0ZDQU1JQXNxQXBBQkloWWdGcElnQ3lvQ21BR1VJQXNxQXBRQkloWWdGcElnQ3lvQ25BR1VremdDR0NBTUlBc3FBcFFCSWhZZ0ZwSWdDeW9DbUFHVUlBc3FBcEFCSWhZZ0ZwSWdDeW9DbkFHVWtqZ0NIQ0FNSUFzcUFwUUJJaFpEQUFBQXdKUWdGcFFnQ3lvQ2tBRWlGa01BQUFEQWxDQVdsRU1BQUlBL2twSTRBaUFnQ1NBVmFpQVhPQUlBSUFrZ0Vtb2dHRGdDQUNBSklCTnFJQms0QWdBZ0NTQVVhaUFhT0FJQUlBc2dCQ0FRYWlvQ0FDSVhPQUl3SUFzZ0JDQVBhaW9DQUNJWU9BSkFJQXNnQkNBT2Fpb0NBQ0laT0FKUUlBb2dFR29nRnpnQ0FDQUtJQTlxSUJnNEFnQWdDaUFPYWlBWk9BSUFJQXNnRENvQ0dDQUxLZ0k0bENBTUtnSUFJQXNxQWpDVUlBd3FBZ3dnQ3lvQ05KU1NramdDQUNBTElBd3FBaHdnQ3lvQ09KUWdEQ29DQkNBTEtnSXdsQ0FNS2dJUUlBc3FBalNVa3BJNEFnUWdDeUFNS2dJZ0lBc3FBamlVSUF3cUFnZ2dDeW9DTUpRZ0RDb0NGQ0FMS2dJMGxKS1NPQUlJSUFzZ0RDb0NHQ0FMS2dKRWxDQU1LZ0lBSUFzcUFqeVVJQXdxQWd3Z0N5b0NRSlNTa2pnQ0RDQUxJQXdxQWh3Z0N5b0NSSlFnRENvQ0JDQUxLZ0k4bENBTUtnSVFJQXNxQWtDVWtwSTRBaEFnQ3lBTUtnSWdJQXNxQWtTVUlBd3FBZ2dnQ3lvQ1BKUWdEQ29DRkNBTEtnSkFsSktTT0FJVUlBc2dEQ29DR0NBTEtnSlFsQ0FNS2dJQUlBc3FBa2lVSUF3cUFnd2dDeW9DVEpTU2tqZ0NHQ0FMSUF3cUFod2dDeW9DVUpRZ0RDb0NCQ0FMS2dKSWxDQU1LZ0lRSUFzcUFreVVrcEk0QWh3Z0N5QU1LZ0lnSUFzcUFsQ1VJQXdxQWdnZ0N5b0NTSlFnRENvQ0ZDQUxLZ0pNbEpLU09BSWdJQXNxQWlBaEZ5QUxLZ0lJSVJnZ0N5b0NGQ0VaSUJFZ0N5b0NHQ0lhSUJxVUlBc3FBZ0FpRmlBV2xDQUxLZ0lNSWhzZ0c1U1Nra01BQUlCQWxDQWFJQXNxQWh3aUhKUWdGaUFMS2dJRUloMlVJQnNnQ3lvQ0VDSWVsSktTUXdBQWdFQ1VFQTAyQWhBZ0VTQWFJQmVVSUJZZ0dKUWdHeUFabEpLU1F3QUFnRUNVSUJ3Z0hKUWdIU0FkbENBZUlCNlVrcEpEQUFDQVFKUVFEVFlDRkNBUklCd2dGNVFnSFNBWWxDQWVJQm1Va3BKREFBQ0FRSlFnRnlBWGxDQVlJQmlVSUJrZ0daU1Nra01BQUlCQWxCQU5OZ0lZSUExQkFXb2hEUXdCQ3dzZ0MwR2dBV29rQUFzYUFDQUFJQUVvQWdnZ0JSQUxCRUFnQVNBQ0lBTWdCQkFUQ3dzM0FDQUFJQUVvQWdnZ0JSQUxCRUFnQVNBQ0lBTWdCQkFURHdzZ0FDZ0NDQ0lBSUFFZ0FpQURJQVFnQlNBQUtBSUFLQUlVRVFNQUM1RUJBQ0FBSUFFb0FnZ2dCQkFMQkVBZ0FTQUNJQU1RRWc4TEFrQWdBQ0FCS0FJQUlBUVFDMFVOQUFKQUlBRW9BaEFnQWtjRVFDQUNJQUVvQWhSSERRRUxJQU5CQVVjTkFTQUJRUUUyQWlBUEN5QUJJQUkyQWhRZ0FTQUROZ0lnSUFFZ0FTZ0NLRUVCYWpZQ0tBSkFJQUVvQWlSQkFVY05BQ0FCS0FJWVFRSkhEUUFnQVVFQk9nQTJDeUFCUVFRMkFpd0xDL1VCQUNBQUlBRW9BZ2dnQkJBTEJFQWdBU0FDSUFNUUVnOExBa0FnQUNBQktBSUFJQVFRQ3dSQUFrQWdBU2dDRUNBQ1J3UkFJQUlnQVNnQ0ZFY05BUXNnQTBFQlJ3MENJQUZCQVRZQ0lBOExJQUVnQXpZQ0lBSkFJQUVvQWl4QkJFWU5BQ0FCUVFBN0FUUWdBQ2dDQ0NJQUlBRWdBaUFDUVFFZ0JDQUFLQUlBS0FJVUVRTUFJQUV0QURWQkFVWUVRQ0FCUVFNMkFpd2dBUzBBTkVVTkFRd0RDeUFCUVFRMkFpd0xJQUVnQWpZQ0ZDQUJJQUVvQWloQkFXbzJBaWdnQVNnQ0pFRUJSdzBCSUFFb0FoaEJBa2NOQVNBQlFRRTZBRFlQQ3lBQUtBSUlJZ0FnQVNBQ0lBTWdCQ0FBS0FJQUtBSVlFUUlBQ3dzeEFDQUFJQUVvQWdoQkFCQUxCRUFnQVNBQ0lBTVFGQThMSUFBb0FnZ2lBQ0FCSUFJZ0F5QUFLQUlBS0FJY0VRQUFDeGdBSUFBZ0FTZ0NDRUVBRUFzRVFDQUJJQUlnQXhBVUN3dWxCUUVHZnlNQVFkQUFheUlFSkFBQ1FBSi9RUUVnQUNBQlFRQVFDdzBBR2tFQUlBRkZEUUFhSXdCQkVHc2lCaVFBSUFZZ0FTZ0NBQ0lEUVFocktBSUFJZ1UyQWd3Z0JpQUJJQVZxTmdJRUlBWWdBMEVFYXlnQ0FEWUNDQ0FHS0FJSUlnTkJ5QWhCQUJBTElRVWdCaWdDQkNFSEFrQWdCUVJBSUFZb0Fnd2hBU01BUVVCcUlnTWtBQ0FEUVVCckpBQkJBQ0FISUFFYklRTU1BUXNnQXlFRkl3QkJRR29pQXlRQUlBRWdCMDRFUUNBRFFnQTNBaHdnQTBJQU53SWtJQU5DQURjQ0xDQURRZ0EzQWhRZ0EwRUFOZ0lRSUFOQnlBZzJBZ3dnQXlBRk5nSUVJQU5CQURZQ1BDQURRb0dBZ0lDQWdJQ0FBVGNDTkNBRElBRTJBZ2dnQlNBRFFRUnFJQWNnQjBFQlFRQWdCU2dDQUNnQ0ZCRURBQ0FCUVFBZ0F5Z0NIQnNoQ0FzZ0EwRkFheVFBSUFnaUF3MEFJd0JCUUdvaUF5UUFJQU5CQURZQ0VDQURRWmdJTmdJTUlBTWdBVFlDQ0NBRFFjZ0lOZ0lFUVFBaEFTQURRUlJxUVFCQkovd0xBQ0FEUVFBMkFqd2dBMEVCT2dBN0lBVWdBMEVFYWlBSFFRRkJBQ0FGS0FJQUtBSVlFUUlBQWtBQ1FBSkFJQU1vQWlnT0FnQUJBZ3NnQXlnQ0dFRUFJQU1vQWlSQkFVWWJRUUFnQXlnQ0lFRUJSaHRCQUNBREtBSXNRUUZHR3lFQkRBRUxJQU1vQWh4QkFVY0VRQ0FES0FJc0RRRWdBeWdDSUVFQlJ3MEJJQU1vQWlSQkFVY05BUXNnQXlnQ0ZDRUJDeUFEUVVCckpBQWdBU0VEQ3lBR1FSQnFKQUJCQUNBRFJRMEFHaUFDS0FJQUlnRkZEUUVnQkVFWWFrRUFRVGo4Q3dBZ0JFRUJPZ0JMSUFSQmZ6WUNJQ0FFSUFBMkFod2dCQ0FETmdJVUlBUkJBVFlDUkNBRElBUkJGR29nQVVFQklBTW9BZ0FvQWh3UkFBQWdCQ2dDTENJQVFRRkdCRUFnQWlBRUtBSWtOZ0lBQ3lBQVFRRkdDeUFFUWRBQWFpUUFEd3NnQkVIUENqWUNDQ0FFUWVVRE5nSUVJQVJCdVFrMkFnQVFDUUFMQ2dBZ0FDQUJRUUFRQ3dzRUFDQUFDd3ZiRVFJQVFZQUlDOG9SQkFrQUFBZ0VBQUJUZERsMGVYQmxYMmx1Wm04QUFBQUFMQWtBQUNRRUFBQUFCQUFBVGpFd1gxOWplSGhoWW1sMk1URTJYMTl6YUdsdFgzUjVjR1ZmYVc1bWIwVUFBQUFBTEFrQUFGUUVBQUFZQkFBQVRqRXdYMTlqZUhoaFltbDJNVEUzWDE5amJHRnpjMTkwZVhCbFgybHVabTlGQUhWdWMybG5ibVZrSUhOb2IzSjBBSFZ1YzJsbmJtVmtJR2x1ZEFCbWJHOWhkQUIxYVc1ME5qUmZkQUFsY3pvbFpEb2dKWE1BZFc1emFXZHVaV1FnWTJoaGNnQXZaVzF6WkdzdlpXMXpZM0pwY0hSbGJpOXplWE4wWlcwdmJHbGlMMnhwWW1ONGVHRmlhUzl6Y21NdmNISnBkbUYwWlY5MGVYQmxhVzVtYnk1amNIQUFZbTl2YkFCMWJuTnBaMjVsWkNCc2IyNW5BSE4wWkRvNmQzTjBjbWx1WndCemRHUTZPbk4wY21sdVp3QnpkR1E2T25VeE5uTjBjbWx1WndCemRHUTZPblV6TW5OMGNtbHVad0JrYjNWaWJHVUFkbTlwWkFCallYUmphR2x1WnlCaElHTnNZWE56SUhkcGRHaHZkWFFnWVc0Z2IySnFaV04wUHdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenh6YUc5eWRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2MyaHZjblErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR2x1ZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4ZFc1emFXZHVaV1FnYVc1MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4bWJHOWhkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhkV2x1ZERoZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGFXNTBPRjkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYVc1ME1UWmZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhhVzUwTVRaZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXbHVkRFkwWDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEdsdWREWTBYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSFZwYm5Rek1sOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eHBiblF6TWw5MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4amFHRnlQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eDFibk5wWjI1bFpDQmphR0Z5UGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenh6YVdkdVpXUWdZMmhoY2o0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4Ykc5dVp6NEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2JHOXVaejRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhaRzkxWW14bFBnQUFBQUFBQUFBQUZBZ0FBQUVBQUFBQ0FBQUFBd0FBQUFRQUFBQUZBQUFBTEFrQUFDQUlBQUFZQkFBQVRqRXdYMTlqZUhoaFltbDJNVEl6WDE5bWRXNWtZVzFsYm5SaGJGOTBlWEJsWDJsdVptOUZBQUFJQUFCUUNBQUFkZ0FBQUFBSUFBQmNDQUFBWWdBQUFBQUlBQUJvQ0FBQVl3QUFBQUFJQUFCMENBQUFhQUFBQUFBSUFBQ0FDQUFBWVFBQUFBQUlBQUNNQ0FBQWN3QUFBQUFJQUFDWUNBQUFkQUFBQUFBSUFBQ2tDQUFBYVFBQUFBQUlBQUN3Q0FBQWFnQUFBQUFJQUFDOENBQUFiQUFBQUFBSUFBRElDQUFBYlFBQUFBQUlBQURVQ0FBQWVBQUFBQUFJQUFEZ0NBQUFlUUFBQUFBSUFBRHNDQUFBWmdBQUFBQUlBQUQ0Q0FBQVpBQUFBQUFBQUFCSUJBQUFBUUFBQUFZQUFBQURBQUFBQkFBQUFBY0FBQUFJQUFBQUNRQUFBQW9BQUFBQUFBQUFUQWtBQUFFQUFBQUxBQUFBQXdBQUFBUUFBQUFIQUFBQURBQUFBQTBBQUFBT0FBQUFMQWtBQUZnSkFBQklCQUFBVGpFd1gxOWplSGhoWW1sMk1USXdYMTl6YVY5amJHRnpjMTkwZVhCbFgybHVabTlGQUFBQUFBUUpBQUNJQ1FBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TV05PVTE4eE1XTm9ZWEpmZEhKaGFYUnpTV05GUlU1VFh6bGhiR3h2WTJGMGIzSkpZMFZGUlVVQUFBUUpBQURRQ1FBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TWGRPVTE4eE1XTm9ZWEpmZEhKaGFYUnpTWGRGUlU1VFh6bGhiR3h2WTJGMGIzSkpkMFZGUlVVQUFBUUpBQUFZQ2dBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TVVJ6VGxOZk1URmphR0Z5WDNSeVlXbDBjMGxFYzBWRlRsTmZPV0ZzYkc5allYUnZja2xFYzBWRlJVVUFBQUFFQ1FBQVpBb0FBRTVUZEROZlh6SXhNbUpoYzJsalgzTjBjbWx1WjBsRWFVNVRYekV4WTJoaGNsOTBjbUZwZEhOSlJHbEZSVTVUWHpsaGJHeHZZMkYwYjNKSlJHbEZSVVZGQUFBQUJBa0FBTEFLQUFCT01UQmxiWE5qY21sd2RHVnVNM1poYkVVQUFBUUpBQURNQ2dBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSlkwVkZBQUFFQ1FBQTlBb0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV0ZGUlFBQUJBa0FBQndMQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsb1JVVUFBQVFKQUFCRUN3QUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpjMFZGQUFBRUNRQUFiQXNBQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1hSRlJRQUFCQWtBQUpRTEFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbHBSVVVBQUFRSkFBQzhDd0FBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKYWtWRkFBQUVDUUFBNUFzQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXeEZSUUFBQkFrQUFBd01BQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGx0UlVVQUFBUUpBQUEwREFBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmVFVkZBQUFFQ1FBQVhBd0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTWGxGUlFBQUJBa0FBSVFNQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsbVJVVUFBQVFKQUFDc0RBQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpaRVZGQUVITUdRc0QwQTRCIjtmdW5jdGlvbiBnZXRCaW5hcnlTeW5jKGZpbGUpe2lmKGZpbGU9PXdhc21CaW5hcnlGaWxlJiZ3YXNtQmluYXJ5KXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkod2FzbUJpbmFyeSl9dmFyIGJpbmFyeT10cnlQYXJzZUFzRGF0YVVSSShmaWxlKTtpZihiaW5hcnkpe3JldHVybiBiaW5hcnl9aWYocmVhZEJpbmFyeSl7cmV0dXJuIHJlYWRCaW5hcnkoZmlsZSl9dGhyb3cgImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1hc3luYyBmdW5jdGlvbiBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpe3JldHVybiBnZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpfWFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzKXt0cnl7dmFyIGJpbmFyeT1hd2FpdCBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpO3ZhciBpbnN0YW5jZT1hd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShiaW5hcnksaW1wb3J0cyk7cmV0dXJuIGluc3RhbmNlfWNhdGNoKHJlYXNvbil7ZXJyKGBmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAke3JlYXNvbn1gKTthYm9ydChyZWFzb24pO319YXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGVBc3luYyhiaW5hcnksYmluYXJ5RmlsZSxpbXBvcnRzKXtyZXR1cm4gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpfWZ1bmN0aW9uIGdldFdhc21JbXBvcnRzKCl7cmV0dXJuIHthOndhc21JbXBvcnRzfX1hc3luYyBmdW5jdGlvbiBjcmVhdGVXYXNtKCl7ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlLG1vZHVsZSl7d2FzbUV4cG9ydHM9aW5zdGFuY2UuZXhwb3J0czt3YXNtTWVtb3J5PXdhc21FeHBvcnRzWyJsIl07dXBkYXRlTWVtb3J5Vmlld3MoKTtyZW1vdmVSdW5EZXBlbmRlbmN5KCk7cmV0dXJuIHdhc21FeHBvcnRzfWFkZFJ1bkRlcGVuZGVuY3koKTtmdW5jdGlvbiByZWNlaXZlSW5zdGFudGlhdGlvblJlc3VsdChyZXN1bHQpe3JldHVybiByZWNlaXZlSW5zdGFuY2UocmVzdWx0WyJpbnN0YW5jZSJdKX12YXIgaW5mbz1nZXRXYXNtSW1wb3J0cygpO2lmKE1vZHVsZVsiaW5zdGFudGlhdGVXYXNtIl0pe3JldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57TW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXShpbmZvLChtb2QsaW5zdCk9PntyZWNlaXZlSW5zdGFuY2UobW9kKTtyZXNvbHZlKG1vZC5leHBvcnRzKTt9KTt9KX10cnl7dmFyIHJlc3VsdD1hd2FpdCBpbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyk7dmFyIGV4cG9ydHM9cmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KTtyZXR1cm4gZXhwb3J0c31jYXRjaChlKXtyZWFkeVByb21pc2VSZWplY3QoZSk7cmV0dXJuIFByb21pc2UucmVqZWN0KGUpfX12YXIgY2FsbFJ1bnRpbWVDYWxsYmFja3M9Y2FsbGJhY2tzPT57d2hpbGUoY2FsbGJhY2tzLmxlbmd0aD4wKXtjYWxsYmFja3Muc2hpZnQoKShNb2R1bGUpO319O3ZhciBvblBvc3RSdW5zPVtdO3ZhciBhZGRPblBvc3RSdW49Y2I9Pm9uUG9zdFJ1bnMudW5zaGlmdChjYik7dmFyIG9uUHJlUnVucz1bXTt2YXIgYWRkT25QcmVSdW49Y2I9Pm9uUHJlUnVucy51bnNoaWZ0KGNiKTtNb2R1bGVbIm5vRXhpdFJ1bnRpbWUiXXx8dHJ1ZTt2YXIgYmFzZTY0RGVjb2RlPWI2ND0+e3ZhciBiMSxiMixpPTAsaj0wLGJMZW5ndGg9YjY0Lmxlbmd0aDt2YXIgb3V0cHV0PW5ldyBVaW50OEFycmF5KChiTGVuZ3RoKjM+PjIpLShiNjRbYkxlbmd0aC0yXT09Ij0iKS0oYjY0W2JMZW5ndGgtMV09PSI9IikpO2Zvcig7aTxiTGVuZ3RoO2krPTQsais9Myl7YjE9YmFzZTY0UmV2ZXJzZUxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTtiMj1iYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildO291dHB1dFtqXT1iYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MnxiMT4+NDtvdXRwdXRbaisxXT1iMTw8NHxiMj4+MjtvdXRwdXRbaisyXT1iMjw8NnxiYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMyldO31yZXR1cm4gb3V0cHV0fTt2YXIgaXNEYXRhVVJJPWZpbGVuYW1lPT5maWxlbmFtZS5zdGFydHNXaXRoKGRhdGFVUklQcmVmaXgpO3ZhciBkYXRhVVJJUHJlZml4PSJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsIjt2YXIgdHJ5UGFyc2VBc0RhdGFVUkk9ZmlsZW5hbWU9PntpZihpc0RhdGFVUkkoZmlsZW5hbWUpKXtyZXR1cm4gYmFzZTY0RGVjb2RlKGZpbGVuYW1lLnNsaWNlKGRhdGFVUklQcmVmaXgubGVuZ3RoKSl9fTt2YXIgX19hYm9ydF9qcz0oKT0+YWJvcnQoIiIpO3ZhciBlbWJpbmRSZXByPXY9PntpZih2PT09bnVsbCl7cmV0dXJuICJudWxsIn12YXIgdD10eXBlb2YgdjtpZih0PT09Im9iamVjdCJ8fHQ9PT0iYXJyYXkifHx0PT09ImZ1bmN0aW9uIil7cmV0dXJuIHYudG9TdHJpbmcoKX1lbHNlIHtyZXR1cm4gIiIrdn19O3ZhciBlbWJpbmRfaW5pdF9jaGFyQ29kZXM9KCk9Pnt2YXIgY29kZXM9bmV3IEFycmF5KDI1Nik7Zm9yKHZhciBpPTA7aTwyNTY7KytpKXtjb2Rlc1tpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpO31lbWJpbmRfY2hhckNvZGVzPWNvZGVzO307dmFyIGVtYmluZF9jaGFyQ29kZXM7dmFyIHJlYWRMYXRpbjFTdHJpbmc9cHRyPT57dmFyIHJldD0iIjt2YXIgYz1wdHI7d2hpbGUoSEVBUFU4W2NdKXtyZXQrPWVtYmluZF9jaGFyQ29kZXNbSEVBUFU4W2MrK11dO31yZXR1cm4gcmV0fTt2YXIgYXdhaXRpbmdEZXBlbmRlbmNpZXM9e307dmFyIHJlZ2lzdGVyZWRUeXBlcz17fTt2YXIgQmluZGluZ0Vycm9yO3ZhciB0aHJvd0JpbmRpbmdFcnJvcj1tZXNzYWdlPT57dGhyb3cgbmV3IEJpbmRpbmdFcnJvcihtZXNzYWdlKX07ZnVuY3Rpb24gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnM9e30pe3ZhciBuYW1lPXJlZ2lzdGVyZWRJbnN0YW5jZS5uYW1lO2lmKCFyYXdUeXBlKXt0aHJvd0JpbmRpbmdFcnJvcihgdHlwZSAiJHtuYW1lfSIgbXVzdCBoYXZlIGEgcG9zaXRpdmUgaW50ZWdlciB0eXBlaWQgcG9pbnRlcmApO31pZihyZWdpc3RlcmVkVHlwZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe2lmKG9wdGlvbnMuaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9ucyl7cmV0dXJufWVsc2Uge3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcmVnaXN0ZXIgdHlwZSAnJHtuYW1lfScgdHdpY2VgKTt9fXJlZ2lzdGVyZWRUeXBlc1tyYXdUeXBlXT1yZWdpc3RlcmVkSW5zdGFuY2U7aWYoYXdhaXRpbmdEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe3ZhciBjYWxsYmFja3M9YXdhaXRpbmdEZXBlbmRlbmNpZXNbcmF3VHlwZV07ZGVsZXRlIGF3YWl0aW5nRGVwZW5kZW5jaWVzW3Jhd1R5cGVdO2NhbGxiYWNrcy5mb3JFYWNoKGNiPT5jYigpKTt9fWZ1bmN0aW9uIHJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zPXt9KXtyZXR1cm4gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnMpfXZhciBpbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXI9KG5hbWUsd2lkdGgsc2lnbmVkKT0+e3N3aXRjaCh3aWR0aCl7Y2FzZSAxOnJldHVybiBzaWduZWQ/cG9pbnRlcj0+SEVBUDhbcG9pbnRlcl06cG9pbnRlcj0+SEVBUFU4W3BvaW50ZXJdO2Nhc2UgMjpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVAxNltwb2ludGVyPj4xXTpwb2ludGVyPT5IRUFQVTE2W3BvaW50ZXI+PjFdO2Nhc2UgNDpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVAzMltwb2ludGVyPj4yXTpwb2ludGVyPT5IRUFQVTMyW3BvaW50ZXI+PjJdO2Nhc2UgODpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVA2NFtwb2ludGVyPj4zXTpwb2ludGVyPT5IRUFQVTY0W3BvaW50ZXI+PjNdO2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCBpbnRlZ2VyIHdpZHRoICgke3dpZHRofSk6ICR7bmFtZX1gKX19O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9iaWdpbnQ9KHByaW1pdGl2ZVR5cGUsbmFtZSxzaXplLG1pblJhbmdlLG1heFJhbmdlKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTt2YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmRleE9mKCJ1IikhPS0xO3JlZ2lzdGVyVHlwZShwcmltaXRpdmVUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTp2YWx1ZT0+dmFsdWUsdG9XaXJlVHlwZTpmdW5jdGlvbihkZXN0cnVjdG9ycyx2YWx1ZSl7aWYodHlwZW9mIHZhbHVlIT0iYmlnaW50IiYmdHlwZW9mIHZhbHVlIT0ibnVtYmVyIil7dGhyb3cgbmV3IFR5cGVFcnJvcihgQ2Fubm90IGNvbnZlcnQgIiR7ZW1iaW5kUmVwcih2YWx1ZSl9IiB0byAke3RoaXMubmFtZX1gKX1pZih0eXBlb2YgdmFsdWU9PSJudW1iZXIiKXt2YWx1ZT1CaWdJbnQodmFsdWUpO31yZXR1cm4gdmFsdWV9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6aW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyKG5hbWUsc2l6ZSwhaXNVbnNpZ25lZFR5cGUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgR2VuZXJpY1dpcmVUeXBlU2l6ZT04O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9ib29sPShyYXdUeXBlLG5hbWUsdHJ1ZVZhbHVlLGZhbHNlVmFsdWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTpmdW5jdGlvbih3dCl7cmV0dXJuICEhd3R9LHRvV2lyZVR5cGU6ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsbyl7cmV0dXJuIG8/dHJ1ZVZhbHVlOmZhbHNlVmFsdWV9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZnVuY3Rpb24ocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBVOFtwb2ludGVyXSl9LGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgZW12YWxfZnJlZWxpc3Q9W107dmFyIGVtdmFsX2hhbmRsZXM9W107dmFyIF9fZW12YWxfZGVjcmVmPWhhbmRsZT0+e2lmKGhhbmRsZT45JiYwPT09LS1lbXZhbF9oYW5kbGVzW2hhbmRsZSsxXSl7ZW12YWxfaGFuZGxlc1toYW5kbGVdPXVuZGVmaW5lZDtlbXZhbF9mcmVlbGlzdC5wdXNoKGhhbmRsZSk7fX07dmFyIGNvdW50X2VtdmFsX2hhbmRsZXM9KCk9PmVtdmFsX2hhbmRsZXMubGVuZ3RoLzItNS1lbXZhbF9mcmVlbGlzdC5sZW5ndGg7dmFyIGluaXRfZW12YWw9KCk9PntlbXZhbF9oYW5kbGVzLnB1c2goMCwxLHVuZGVmaW5lZCwxLG51bGwsMSx0cnVlLDEsZmFsc2UsMSk7TW9kdWxlWyJjb3VudF9lbXZhbF9oYW5kbGVzIl09Y291bnRfZW12YWxfaGFuZGxlczt9O3ZhciBFbXZhbD17dG9WYWx1ZTpoYW5kbGU9PntpZighaGFuZGxlKXt0aHJvd0JpbmRpbmdFcnJvcigiQ2Fubm90IHVzZSBkZWxldGVkIHZhbC4gaGFuZGxlID0gIitoYW5kbGUpO31yZXR1cm4gZW12YWxfaGFuZGxlc1toYW5kbGVdfSx0b0hhbmRsZTp2YWx1ZT0+e3N3aXRjaCh2YWx1ZSl7Y2FzZSB1bmRlZmluZWQ6cmV0dXJuIDI7Y2FzZSBudWxsOnJldHVybiA0O2Nhc2UgdHJ1ZTpyZXR1cm4gNjtjYXNlIGZhbHNlOnJldHVybiA4O2RlZmF1bHQ6e2NvbnN0IGhhbmRsZT1lbXZhbF9mcmVlbGlzdC5wb3AoKXx8ZW12YWxfaGFuZGxlcy5sZW5ndGg7ZW12YWxfaGFuZGxlc1toYW5kbGVdPXZhbHVlO2VtdmFsX2hhbmRsZXNbaGFuZGxlKzFdPTE7cmV0dXJuIGhhbmRsZX19fX07ZnVuY3Rpb24gcmVhZFBvaW50ZXIocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBVMzJbcG9pbnRlcj4+Ml0pfXZhciBFbVZhbFR5cGU9e25hbWU6ImVtc2NyaXB0ZW46OnZhbCIsZnJvbVdpcmVUeXBlOmhhbmRsZT0+e3ZhciBydj1FbXZhbC50b1ZhbHVlKGhhbmRsZSk7X19lbXZhbF9kZWNyZWYoaGFuZGxlKTtyZXR1cm4gcnZ9LHRvV2lyZVR5cGU6KGRlc3RydWN0b3JzLHZhbHVlKT0+RW12YWwudG9IYW5kbGUodmFsdWUpLGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6cmVhZFBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbD1yYXdUeXBlPT5yZWdpc3RlclR5cGUocmF3VHlwZSxFbVZhbFR5cGUpO3ZhciBmbG9hdFJlYWRWYWx1ZUZyb21Qb2ludGVyPShuYW1lLHdpZHRoKT0+e3N3aXRjaCh3aWR0aCl7Y2FzZSA0OnJldHVybiBmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEYzMltwb2ludGVyPj4yXSl9O2Nhc2UgODpyZXR1cm4gZnVuY3Rpb24ocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBGNjRbcG9pbnRlcj4+M10pfTtkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgZmxvYXQgd2lkdGggKCR7d2lkdGh9KTogJHtuYW1lfWApfX07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0PShyYXdUeXBlLG5hbWUsc2l6ZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWUsZnJvbVdpcmVUeXBlOnZhbHVlPT52YWx1ZSx0b1dpcmVUeXBlOihkZXN0cnVjdG9ycyx2YWx1ZSk9PnZhbHVlLGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcj0ocHJpbWl0aXZlVHlwZSxuYW1lLHNpemUsbWluUmFuZ2UsbWF4UmFuZ2UpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlO2lmKG1pblJhbmdlPT09MCl7dmFyIGJpdHNoaWZ0PTMyLTgqc2l6ZTtmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlPDxiaXRzaGlmdD4+PmJpdHNoaWZ0O312YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmNsdWRlcygidW5zaWduZWQiKTt2YXIgY2hlY2tBc3NlcnRpb25zPSh2YWx1ZSx0b1R5cGVOYW1lKT0+e307dmFyIHRvV2lyZVR5cGU7aWYoaXNVbnNpZ25lZFR5cGUpe3RvV2lyZVR5cGU9ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsdmFsdWUpe2NoZWNrQXNzZXJ0aW9ucyh2YWx1ZSx0aGlzLm5hbWUpO3JldHVybiB2YWx1ZT4+PjB9O31lbHNlIHt0b1dpcmVUeXBlPWZ1bmN0aW9uKGRlc3RydWN0b3JzLHZhbHVlKXtjaGVja0Fzc2VydGlvbnModmFsdWUsdGhpcy5uYW1lKTtyZXR1cm4gdmFsdWV9O31yZWdpc3RlclR5cGUocHJpbWl0aXZlVHlwZSx7bmFtZSxmcm9tV2lyZVR5cGUsdG9XaXJlVHlwZSxhcmdQYWNrQWR2YW5jZTpHZW5lcmljV2lyZVR5cGVTaXplLHJlYWRWYWx1ZUZyb21Qb2ludGVyOmludGVnZXJSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUsbWluUmFuZ2UhPT0wKSxkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3PShyYXdUeXBlLGRhdGFUeXBlSW5kZXgsbmFtZSk9Pnt2YXIgdHlwZU1hcHBpbmc9W0ludDhBcnJheSxVaW50OEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5LEJpZ0ludDY0QXJyYXksQmlnVWludDY0QXJyYXldO3ZhciBUQT10eXBlTWFwcGluZ1tkYXRhVHlwZUluZGV4XTtmdW5jdGlvbiBkZWNvZGVNZW1vcnlWaWV3KGhhbmRsZSl7dmFyIHNpemU9SEVBUFUzMltoYW5kbGU+PjJdO3ZhciBkYXRhPUhFQVBVMzJbaGFuZGxlKzQ+PjJdO3JldHVybiBuZXcgVEEoSEVBUDguYnVmZmVyLGRhdGEsc2l6ZSl9bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTpkZWNvZGVNZW1vcnlWaWV3LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZGVjb2RlTWVtb3J5Vmlld30se2lnbm9yZUR1cGxpY2F0ZVJlZ2lzdHJhdGlvbnM6dHJ1ZX0pO307dmFyIHN0cmluZ1RvVVRGOEFycmF5PShzdHIsaGVhcCxvdXRJZHgsbWF4Qnl0ZXNUb1dyaXRlKT0+e2lmKCEobWF4Qnl0ZXNUb1dyaXRlPjApKXJldHVybiAwO3ZhciBzdGFydElkeD1vdXRJZHg7dmFyIGVuZElkeD1vdXRJZHgrbWF4Qnl0ZXNUb1dyaXRlLTE7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIHU9c3RyLmNoYXJDb2RlQXQoaSk7aWYodT49NTUyOTYmJnU8PTU3MzQzKXt2YXIgdTE9c3RyLmNoYXJDb2RlQXQoKytpKTt1PTY1NTM2KygodSYxMDIzKTw8MTApfHUxJjEwMjM7fWlmKHU8PTEyNyl7aWYob3V0SWR4Pj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109dTt9ZWxzZSBpZih1PD0yMDQ3KXtpZihvdXRJZHgrMT49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTE5Mnx1Pj42O2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO31lbHNlIGlmKHU8PTY1NTM1KXtpZihvdXRJZHgrMj49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTIyNHx1Pj4xMjtoZWFwW291dElkeCsrXT0xMjh8dT4+NiY2MztoZWFwW291dElkeCsrXT0xMjh8dSY2Mzt9ZWxzZSB7aWYob3V0SWR4KzM+PWVuZElkeClicmVhaztoZWFwW291dElkeCsrXT0yNDB8dT4+MTg7aGVhcFtvdXRJZHgrK109MTI4fHU+PjEyJjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1Pj42JjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO319aGVhcFtvdXRJZHhdPTA7cmV0dXJuIG91dElkeC1zdGFydElkeH07dmFyIHN0cmluZ1RvVVRGOD0oc3RyLG91dFB0cixtYXhCeXRlc1RvV3JpdGUpPT5zdHJpbmdUb1VURjhBcnJheShzdHIsSEVBUFU4LG91dFB0cixtYXhCeXRlc1RvV3JpdGUpO3ZhciBsZW5ndGhCeXRlc1VURjg9c3RyPT57dmFyIGxlbj0wO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe3ZhciBjPXN0ci5jaGFyQ29kZUF0KGkpO2lmKGM8PTEyNyl7bGVuKys7fWVsc2UgaWYoYzw9MjA0Nyl7bGVuKz0yO31lbHNlIGlmKGM+PTU1Mjk2JiZjPD01NzM0Myl7bGVuKz00OysraTt9ZWxzZSB7bGVuKz0zO319cmV0dXJuIGxlbn07dmFyIFVURjhEZWNvZGVyPXR5cGVvZiBUZXh0RGVjb2RlciE9InVuZGVmaW5lZCI/bmV3IFRleHREZWNvZGVyOnVuZGVmaW5lZDt2YXIgVVRGOEFycmF5VG9TdHJpbmc9KGhlYXBPckFycmF5LGlkeD0wLG1heEJ5dGVzVG9SZWFkPU5hTik9Pnt2YXIgZW5kSWR4PWlkeCttYXhCeXRlc1RvUmVhZDt2YXIgZW5kUHRyPWlkeDt3aGlsZShoZWFwT3JBcnJheVtlbmRQdHJdJiYhKGVuZFB0cj49ZW5kSWR4KSkrK2VuZFB0cjtpZihlbmRQdHItaWR4PjE2JiZoZWFwT3JBcnJheS5idWZmZXImJlVURjhEZWNvZGVyKXtyZXR1cm4gVVRGOERlY29kZXIuZGVjb2RlKGhlYXBPckFycmF5LnN1YmFycmF5KGlkeCxlbmRQdHIpKX12YXIgc3RyPSIiO3doaWxlKGlkeDxlbmRQdHIpe3ZhciB1MD1oZWFwT3JBcnJheVtpZHgrK107aWYoISh1MCYxMjgpKXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO2NvbnRpbnVlfXZhciB1MT1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjIyNCk9PTE5Mil7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKCh1MCYzMSk8PDZ8dTEpO2NvbnRpbnVlfXZhciB1Mj1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjI0MCk9PTIyNCl7dTA9KHUwJjE1KTw8MTJ8dTE8PDZ8dTI7fWVsc2Uge3UwPSh1MCY3KTw8MTh8dTE8PDEyfHUyPDw2fGhlYXBPckFycmF5W2lkeCsrXSY2Mzt9aWYodTA8NjU1MzYpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1MCk7fWVsc2Uge3ZhciBjaD11MC02NTUzNjtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8Y2g+PjEwLDU2MzIwfGNoJjEwMjMpO319cmV0dXJuIHN0cn07dmFyIFVURjhUb1N0cmluZz0ocHRyLG1heEJ5dGVzVG9SZWFkKT0+cHRyP1VURjhBcnJheVRvU3RyaW5nKEhFQVBVOCxwdHIsbWF4Qnl0ZXNUb1JlYWQpOiIiO3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9zdGRfc3RyaW5nPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZSh2YWx1ZSl7dmFyIGxlbmd0aD1IRUFQVTMyW3ZhbHVlPj4yXTt2YXIgcGF5bG9hZD12YWx1ZSs0O3ZhciBzdHI7dmFyIGk7IHt2YXIgZGVjb2RlU3RhcnRQdHI9cGF5bG9hZDtmb3IodmFyIGk9MDtpPD1sZW5ndGg7KytpKXt2YXIgY3VycmVudEJ5dGVQdHI9cGF5bG9hZCtpO2lmKGk9PWxlbmd0aHx8SEVBUFU4W2N1cnJlbnRCeXRlUHRyXT09MCl7dmFyIG1heFJlYWQ9Y3VycmVudEJ5dGVQdHItZGVjb2RlU3RhcnRQdHI7dmFyIHN0cmluZ1NlZ21lbnQ9VVRGOFRvU3RyaW5nKGRlY29kZVN0YXJ0UHRyLG1heFJlYWQpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyKzE7fX19X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LHRvV2lyZVR5cGUoZGVzdHJ1Y3RvcnMsdmFsdWUpe2lmKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3ZhbHVlPW5ldyBVaW50OEFycmF5KHZhbHVlKTt9dmFyIGxlbmd0aDt2YXIgdmFsdWVJc09mVHlwZVN0cmluZz10eXBlb2YgdmFsdWU9PSJzdHJpbmciO2lmKCEodmFsdWVJc09mVHlwZVN0cmluZ3x8dmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIEludDhBcnJheSkpe3Rocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIHN0ZDo6c3RyaW5nIik7fWlmKHZhbHVlSXNPZlR5cGVTdHJpbmcpe2xlbmd0aD1sZW5ndGhCeXRlc1VURjgodmFsdWUpO31lbHNlIHtsZW5ndGg9dmFsdWUubGVuZ3RoO312YXIgYmFzZT1fbWFsbG9jKDQrbGVuZ3RoKzEpO3ZhciBwdHI9YmFzZSs0O0hFQVBVMzJbYmFzZT4+Ml09bGVuZ3RoO2lmKHZhbHVlSXNPZlR5cGVTdHJpbmcpe3N0cmluZ1RvVVRGOCh2YWx1ZSxwdHIsbGVuZ3RoKzEpO31lbHNlIHtpZih2YWx1ZUlzT2ZUeXBlU3RyaW5nKXtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe3ZhciBjaGFyQ29kZT12YWx1ZS5jaGFyQ29kZUF0KGkpO2lmKGNoYXJDb2RlPjI1NSl7X2ZyZWUoYmFzZSk7dGhyb3dCaW5kaW5nRXJyb3IoIlN0cmluZyBoYXMgVVRGLTE2IGNvZGUgdW5pdHMgdGhhdCBkbyBub3QgZml0IGluIDggYml0cyIpO31IRUFQVThbcHRyK2ldPWNoYXJDb2RlO319ZWxzZSB7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtIRUFQVThbcHRyK2ldPXZhbHVlW2ldO319fWlmKGRlc3RydWN0b3JzIT09bnVsbCl7ZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSxiYXNlKTt9cmV0dXJuIGJhc2V9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6cmVhZFBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uKHB0cil7X2ZyZWUocHRyKTt9fSk7fTt2YXIgVVRGMTZEZWNvZGVyPXR5cGVvZiBUZXh0RGVjb2RlciE9InVuZGVmaW5lZCI/bmV3IFRleHREZWNvZGVyKCJ1dGYtMTZsZSIpOnVuZGVmaW5lZDt2YXIgVVRGMTZUb1N0cmluZz0ocHRyLG1heEJ5dGVzVG9SZWFkKT0+e3ZhciBlbmRQdHI9cHRyO3ZhciBpZHg9ZW5kUHRyPj4xO3ZhciBtYXhJZHg9aWR4K21heEJ5dGVzVG9SZWFkLzI7d2hpbGUoIShpZHg+PW1heElkeCkmJkhFQVBVMTZbaWR4XSkrK2lkeDtlbmRQdHI9aWR4PDwxO2lmKGVuZFB0ci1wdHI+MzImJlVURjE2RGVjb2RlcilyZXR1cm4gVVRGMTZEZWNvZGVyLmRlY29kZShIRUFQVTguc3ViYXJyYXkocHRyLGVuZFB0cikpO3ZhciBzdHI9IiI7Zm9yKHZhciBpPTA7IShpPj1tYXhCeXRlc1RvUmVhZC8yKTsrK2kpe3ZhciBjb2RlVW5pdD1IRUFQMTZbcHRyK2kqMj4+MV07aWYoY29kZVVuaXQ9PTApYnJlYWs7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVVbml0KTt9cmV0dXJuIHN0cn07dmFyIHN0cmluZ1RvVVRGMTY9KHN0cixvdXRQdHIsbWF4Qnl0ZXNUb1dyaXRlKT0+e21heEJ5dGVzVG9Xcml0ZT8/PTIxNDc0ODM2NDc7aWYobWF4Qnl0ZXNUb1dyaXRlPDIpcmV0dXJuIDA7bWF4Qnl0ZXNUb1dyaXRlLT0yO3ZhciBzdGFydFB0cj1vdXRQdHI7dmFyIG51bUNoYXJzVG9Xcml0ZT1tYXhCeXRlc1RvV3JpdGU8c3RyLmxlbmd0aCoyP21heEJ5dGVzVG9Xcml0ZS8yOnN0ci5sZW5ndGg7Zm9yKHZhciBpPTA7aTxudW1DaGFyc1RvV3JpdGU7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7SEVBUDE2W291dFB0cj4+MV09Y29kZVVuaXQ7b3V0UHRyKz0yO31IRUFQMTZbb3V0UHRyPj4xXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjE2PXN0cj0+c3RyLmxlbmd0aCoyO3ZhciBVVEYzMlRvU3RyaW5nPShwdHIsbWF4Qnl0ZXNUb1JlYWQpPT57dmFyIGk9MDt2YXIgc3RyPSIiO3doaWxlKCEoaT49bWF4Qnl0ZXNUb1JlYWQvNCkpe3ZhciB1dGYzMj1IRUFQMzJbcHRyK2kqND4+Ml07aWYodXRmMzI9PTApYnJlYWs7KytpO2lmKHV0ZjMyPj02NTUzNil7dmFyIGNoPXV0ZjMyLTY1NTM2O3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxjaD4+MTAsNTYzMjB8Y2gmMTAyMyk7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1dGYzMik7fX1yZXR1cm4gc3RyfTt2YXIgc3RyaW5nVG9VVEYzMj0oc3RyLG91dFB0cixtYXhCeXRlc1RvV3JpdGUpPT57bWF4Qnl0ZXNUb1dyaXRlPz89MjE0NzQ4MzY0NztpZihtYXhCeXRlc1RvV3JpdGU8NClyZXR1cm4gMDt2YXIgc3RhcnRQdHI9b3V0UHRyO3ZhciBlbmRQdHI9c3RhcnRQdHIrbWF4Qnl0ZXNUb1dyaXRlLTQ7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGNvZGVVbml0PXN0ci5jaGFyQ29kZUF0KGkpO2lmKGNvZGVVbml0Pj01NTI5NiYmY29kZVVuaXQ8PTU3MzQzKXt2YXIgdHJhaWxTdXJyb2dhdGU9c3RyLmNoYXJDb2RlQXQoKytpKTtjb2RlVW5pdD02NTUzNisoKGNvZGVVbml0JjEwMjMpPDwxMCl8dHJhaWxTdXJyb2dhdGUmMTAyMzt9SEVBUDMyW291dFB0cj4+Ml09Y29kZVVuaXQ7b3V0UHRyKz00O2lmKG91dFB0cis0PmVuZFB0cilicmVha31IRUFQMzJbb3V0UHRyPj4yXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjMyPXN0cj0+e3ZhciBsZW49MDtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7aWYoY29kZVVuaXQ+PTU1Mjk2JiZjb2RlVW5pdDw9NTczNDMpKytpO2xlbis9NDt9cmV0dXJuIGxlbn07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nPShyYXdUeXBlLGNoYXJTaXplLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBkZWNvZGVTdHJpbmcsZW5jb2RlU3RyaW5nLHJlYWRDaGFyQXQsbGVuZ3RoQnl0ZXNVVEY7aWYoY2hhclNpemU9PT0yKXtkZWNvZGVTdHJpbmc9VVRGMTZUb1N0cmluZztlbmNvZGVTdHJpbmc9c3RyaW5nVG9VVEYxNjtsZW5ndGhCeXRlc1VURj1sZW5ndGhCeXRlc1VURjE2O3JlYWRDaGFyQXQ9cG9pbnRlcj0+SEVBUFUxNltwb2ludGVyPj4xXTt9ZWxzZSBpZihjaGFyU2l6ZT09PTQpe2RlY29kZVN0cmluZz1VVEYzMlRvU3RyaW5nO2VuY29kZVN0cmluZz1zdHJpbmdUb1VURjMyO2xlbmd0aEJ5dGVzVVRGPWxlbmd0aEJ5dGVzVVRGMzI7cmVhZENoYXJBdD1wb2ludGVyPT5IRUFQVTMyW3BvaW50ZXI+PjJdO31yZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZSxmcm9tV2lyZVR5cGU6dmFsdWU9Pnt2YXIgbGVuZ3RoPUhFQVBVMzJbdmFsdWU+PjJdO3ZhciBzdHI7dmFyIGRlY29kZVN0YXJ0UHRyPXZhbHVlKzQ7Zm9yKHZhciBpPTA7aTw9bGVuZ3RoOysraSl7dmFyIGN1cnJlbnRCeXRlUHRyPXZhbHVlKzQraSpjaGFyU2l6ZTtpZihpPT1sZW5ndGh8fHJlYWRDaGFyQXQoY3VycmVudEJ5dGVQdHIpPT0wKXt2YXIgbWF4UmVhZEJ5dGVzPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PWRlY29kZVN0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkQnl0ZXMpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyK2NoYXJTaXplO319X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LHRvV2lyZVR5cGU6KGRlc3RydWN0b3JzLHZhbHVlKT0+e2lmKCEodHlwZW9mIHZhbHVlPT0ic3RyaW5nIikpe3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIEMrKyBzdHJpbmcgdHlwZSAke25hbWV9YCk7fXZhciBsZW5ndGg9bGVuZ3RoQnl0ZXNVVEYodmFsdWUpO3ZhciBwdHI9X21hbGxvYyg0K2xlbmd0aCtjaGFyU2l6ZSk7SEVBUFUzMltwdHI+PjJdPWxlbmd0aC9jaGFyU2l6ZTtlbmNvZGVTdHJpbmcodmFsdWUscHRyKzQsbGVuZ3RoK2NoYXJTaXplKTtpZihkZXN0cnVjdG9ycyE9PW51bGwpe2Rlc3RydWN0b3JzLnB1c2goX2ZyZWUscHRyKTt9cmV0dXJuIHB0cn0sYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpyZWFkUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb24ocHRyKXtfZnJlZShwdHIpO319KTt9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl92b2lkPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtpc1ZvaWQ6dHJ1ZSxuYW1lLGFyZ1BhY2tBZHZhbmNlOjAsZnJvbVdpcmVUeXBlOigpPT51bmRlZmluZWQsdG9XaXJlVHlwZTooZGVzdHJ1Y3RvcnMsbyk9PnVuZGVmaW5lZH0pO307dmFyIGdldEhlYXBNYXg9KCk9PjIxNDc0ODM2NDg7dmFyIGFsaWduTWVtb3J5PShzaXplLGFsaWdubWVudCk9Pk1hdGguY2VpbChzaXplL2FsaWdubWVudCkqYWxpZ25tZW50O3ZhciBncm93TWVtb3J5PXNpemU9Pnt2YXIgYj13YXNtTWVtb3J5LmJ1ZmZlcjt2YXIgcGFnZXM9KHNpemUtYi5ieXRlTGVuZ3RoKzY1NTM1KS82NTUzNnwwO3RyeXt3YXNtTWVtb3J5Lmdyb3cocGFnZXMpO3VwZGF0ZU1lbW9yeVZpZXdzKCk7cmV0dXJuIDF9Y2F0Y2goZSl7fX07dmFyIF9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwPXJlcXVlc3RlZFNpemU9Pnt2YXIgb2xkU2l6ZT1IRUFQVTgubGVuZ3RoO3JlcXVlc3RlZFNpemU+Pj49MDt2YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX1mb3IodmFyIGN1dERvd249MTtjdXREb3duPD00O2N1dERvd24qPTIpe3ZhciBvdmVyR3Jvd25IZWFwU2l6ZT1vbGRTaXplKigxKy4yL2N1dERvd24pO292ZXJHcm93bkhlYXBTaXplPU1hdGgubWluKG92ZXJHcm93bkhlYXBTaXplLHJlcXVlc3RlZFNpemUrMTAwNjYzMjk2KTt2YXIgbmV3U2l6ZT1NYXRoLm1pbihtYXhIZWFwU2l6ZSxhbGlnbk1lbW9yeShNYXRoLm1heChyZXF1ZXN0ZWRTaXplLG92ZXJHcm93bkhlYXBTaXplKSw2NTUzNikpO3ZhciByZXBsYWNlbWVudD1ncm93TWVtb3J5KG5ld1NpemUpO2lmKHJlcGxhY2VtZW50KXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfTtmb3IodmFyIGJhc2U2NFJldmVyc2VMb29rdXA9bmV3IFVpbnQ4QXJyYXkoMTIzKSxpPTI1O2k+PTA7LS1pKXtiYXNlNjRSZXZlcnNlTG9va3VwWzQ4K2ldPTUyK2k7YmFzZTY0UmV2ZXJzZUxvb2t1cFs2NStpXT1pO2Jhc2U2NFJldmVyc2VMb29rdXBbOTcraV09MjYraTt9YmFzZTY0UmV2ZXJzZUxvb2t1cFs0M109NjI7YmFzZTY0UmV2ZXJzZUxvb2t1cFs0N109NjM7ZW1iaW5kX2luaXRfY2hhckNvZGVzKCk7QmluZGluZ0Vycm9yPU1vZHVsZVsiQmluZGluZ0Vycm9yIl09Y2xhc3MgQmluZGluZ0Vycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IobWVzc2FnZSl7c3VwZXIobWVzc2FnZSk7dGhpcy5uYW1lPSJCaW5kaW5nRXJyb3IiO319O01vZHVsZVsiSW50ZXJuYWxFcnJvciJdPWNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihtZXNzYWdlKXtzdXBlcihtZXNzYWdlKTt0aGlzLm5hbWU9IkludGVybmFsRXJyb3IiO319O2luaXRfZW12YWwoKTt2YXIgd2FzbUltcG9ydHM9e2o6X19hYm9ydF9qcyxlOl9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludCxoOl9fZW1iaW5kX3JlZ2lzdGVyX2Jvb2wsZjpfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbCxkOl9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0LGI6X19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcixhOl9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3LGc6X19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZyxjOl9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nLGk6X19lbWJpbmRfcmVnaXN0ZXJfdm9pZCxrOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwfTt2YXIgd2FzbUV4cG9ydHM9YXdhaXQgY3JlYXRlV2FzbSgpO3dhc21FeHBvcnRzWyJtIl07TW9kdWxlWyJfcGFjayJdPXdhc21FeHBvcnRzWyJuIl07dmFyIF9tYWxsb2M9TW9kdWxlWyJfbWFsbG9jIl09d2FzbUV4cG9ydHNbIm8iXTt2YXIgX2ZyZWU9TW9kdWxlWyJfZnJlZSJdPXdhc21FeHBvcnRzWyJwIl07ZnVuY3Rpb24gcnVuKCl7aWYocnVuRGVwZW5kZW5jaWVzPjApe2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW47cmV0dXJufXByZVJ1bigpO2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtkZXBlbmRlbmNpZXNGdWxmaWxsZWQ9cnVuO3JldHVybn1mdW5jdGlvbiBkb1J1bigpe01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlKE1vZHVsZSk7TW9kdWxlWyJvblJ1bnRpbWVJbml0aWFsaXplZCJdPy4oKTtwb3N0UnVuKCk7fWlmKE1vZHVsZVsic2V0U3RhdHVzIl0pe01vZHVsZVsic2V0U3RhdHVzIl0oIlJ1bm5pbmcuLi4iKTtzZXRUaW1lb3V0KCgpPT57c2V0VGltZW91dCgoKT0+TW9kdWxlWyJzZXRTdGF0dXMiXSgiIiksMSk7ZG9SdW4oKTt9LDEpO31lbHNlIHtkb1J1bigpO319aWYoTW9kdWxlWyJwcmVJbml0Il0pe2lmKHR5cGVvZiBNb2R1bGVbInByZUluaXQiXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZUluaXQiXT1bTW9kdWxlWyJwcmVJbml0Il1dO3doaWxlKE1vZHVsZVsicHJlSW5pdCJdLmxlbmd0aD4wKXtNb2R1bGVbInByZUluaXQiXS5wb3AoKSgpO319cnVuKCk7bW9kdWxlUnRuPXJlYWR5UHJvbWlzZTsNCg0KDQogICAgcmV0dXJuIG1vZHVsZVJ0bjsNCiAgfQ0KICApOw0KICB9KSgpOwoKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogIGxldCB3YXNtTW9kdWxlOwogIGFzeW5jIGZ1bmN0aW9uIGluaXRXYXNtKCkgewogICAgICB3YXNtTW9kdWxlID0gYXdhaXQgbG9hZFdhc20oKTsKICB9CiAgbGV0IGFsbG9jYXRlZFZlcnRleENvdW50ID0gMDsKICBjb25zdCB1cGRhdGVRdWV1ZSA9IG5ldyBBcnJheSgpOwogIGxldCBydW5uaW5nID0gZmFsc2U7CiAgbGV0IGxvYWRpbmcgPSBmYWxzZTsKICBsZXQgcG9zaXRpb25zUHRyOwogIGxldCByb3RhdGlvbnNQdHI7CiAgbGV0IHNjYWxlc1B0cjsKICBsZXQgY29sb3JzUHRyOwogIGxldCBzZWxlY3Rpb25QdHI7CiAgbGV0IGRhdGFQdHI7CiAgbGV0IHdvcmxkUG9zaXRpb25zUHRyOwogIGxldCB3b3JsZFJvdGF0aW9uc1B0cjsKICBsZXQgd29ybGRTY2FsZXNQdHI7CiAgY29uc3QgcGFjayA9IGFzeW5jIChzcGxhdCkgPT4gewogICAgICB3aGlsZSAobG9hZGluZykgewogICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMCkpOwogICAgICB9CiAgICAgIGlmICghd2FzbU1vZHVsZSkgewogICAgICAgICAgbG9hZGluZyA9IHRydWU7CiAgICAgICAgICBhd2FpdCBpbml0V2FzbSgpOwogICAgICAgICAgbG9hZGluZyA9IGZhbHNlOwogICAgICB9CiAgICAgIGNvbnN0IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50ID0gTWF0aC5wb3coMiwgTWF0aC5jZWlsKE1hdGgubG9nMihzcGxhdC52ZXJ0ZXhDb3VudCkpKTsKICAgICAgaWYgKHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50ID4gYWxsb2NhdGVkVmVydGV4Q291bnQpIHsKICAgICAgICAgIGlmIChhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA+IDApIHsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHBvc2l0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShyb3RhdGlvbnNQdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoc2NhbGVzUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKGNvbG9yc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShzZWxlY3Rpb25QdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoZGF0YVB0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFBvc2l0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFJvdGF0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFNjYWxlc1B0cik7CiAgICAgICAgICB9CiAgICAgICAgICBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA9IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50OwogICAgICAgICAgcG9zaXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgcm90YXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDQgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgc2NhbGVzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgY29sb3JzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDQgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCk7CiAgICAgICAgICBzZWxlY3Rpb25QdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoYWxsb2NhdGVkVmVydGV4Q291bnQpOwogICAgICAgICAgZGF0YVB0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyg4ICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIHdvcmxkUG9zaXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgd29ybGRSb3RhdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoNCAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICB3b3JsZFNjYWxlc1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYygzICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgfQogICAgICB3YXNtTW9kdWxlLkhFQVBGMzIuc2V0KHNwbGF0LnBvc2l0aW9ucywgcG9zaXRpb25zUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuSEVBUEYzMi5zZXQoc3BsYXQucm90YXRpb25zLCByb3RhdGlvbnNQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5IRUFQRjMyLnNldChzcGxhdC5zY2FsZXMsIHNjYWxlc1B0ciAvIDQpOwogICAgICB3YXNtTW9kdWxlLkhFQVBVOC5zZXQoc3BsYXQuY29sb3JzLCBjb2xvcnNQdHIpOwogICAgICB3YXNtTW9kdWxlLkhFQVBVOC5zZXQoc3BsYXQuc2VsZWN0aW9uLCBzZWxlY3Rpb25QdHIpOwogICAgICB3YXNtTW9kdWxlLl9wYWNrKHNwbGF0LnNlbGVjdGVkLCBzcGxhdC52ZXJ0ZXhDb3VudCwgcG9zaXRpb25zUHRyLCByb3RhdGlvbnNQdHIsIHNjYWxlc1B0ciwgY29sb3JzUHRyLCBzZWxlY3Rpb25QdHIsIGRhdGFQdHIsIHdvcmxkUG9zaXRpb25zUHRyLCB3b3JsZFJvdGF0aW9uc1B0ciwgd29ybGRTY2FsZXNQdHIpOwogICAgICBjb25zdCBvdXREYXRhID0gbmV3IFVpbnQzMkFycmF5KHdhc21Nb2R1bGUuSEVBUFUzMi5idWZmZXIsIGRhdGFQdHIsIHNwbGF0LnZlcnRleENvdW50ICogOCk7CiAgICAgIGNvbnN0IGRldGFjaGVkRGF0YSA9IG5ldyBVaW50MzJBcnJheShvdXREYXRhLnNsaWNlKCkuYnVmZmVyKTsKICAgICAgY29uc3Qgd29ybGRQb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KHdhc21Nb2R1bGUuSEVBUEYzMi5idWZmZXIsIHdvcmxkUG9zaXRpb25zUHRyLCBzcGxhdC52ZXJ0ZXhDb3VudCAqIDMpOwogICAgICBjb25zdCBkZXRhY2hlZFdvcmxkUG9zaXRpb25zID0gbmV3IEZsb2F0MzJBcnJheSh3b3JsZFBvc2l0aW9ucy5zbGljZSgpLmJ1ZmZlcik7CiAgICAgIGNvbnN0IHdvcmxkUm90YXRpb25zID0gbmV3IEZsb2F0MzJBcnJheSh3YXNtTW9kdWxlLkhFQVBGMzIuYnVmZmVyLCB3b3JsZFJvdGF0aW9uc1B0ciwgc3BsYXQudmVydGV4Q291bnQgKiA0KTsKICAgICAgY29uc3QgZGV0YWNoZWRXb3JsZFJvdGF0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkod29ybGRSb3RhdGlvbnMuc2xpY2UoKS5idWZmZXIpOwogICAgICBjb25zdCB3b3JsZFNjYWxlcyA9IG5ldyBGbG9hdDMyQXJyYXkod2FzbU1vZHVsZS5IRUFQRjMyLmJ1ZmZlciwgd29ybGRTY2FsZXNQdHIsIHNwbGF0LnZlcnRleENvdW50ICogMyk7CiAgICAgIGNvbnN0IGRldGFjaGVkV29ybGRTY2FsZXMgPSBuZXcgRmxvYXQzMkFycmF5KHdvcmxkU2NhbGVzLnNsaWNlKCkuYnVmZmVyKTsKICAgICAgY29uc3QgcmVzcG9uc2UgPSB7CiAgICAgICAgICBkYXRhOiBkZXRhY2hlZERhdGEsCiAgICAgICAgICB3b3JsZFBvc2l0aW9uczogZGV0YWNoZWRXb3JsZFBvc2l0aW9ucywKICAgICAgICAgIHdvcmxkUm90YXRpb25zOiBkZXRhY2hlZFdvcmxkUm90YXRpb25zLAogICAgICAgICAgd29ybGRTY2FsZXM6IGRldGFjaGVkV29ybGRTY2FsZXMsCiAgICAgICAgICBvZmZzZXQ6IHNwbGF0Lm9mZnNldCwKICAgICAgICAgIHZlcnRleENvdW50OiBzcGxhdC52ZXJ0ZXhDb3VudCwKICAgICAgICAgIHBvc2l0aW9uczogc3BsYXQucG9zaXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJvdGF0aW9uczogc3BsYXQucm90YXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHNjYWxlczogc3BsYXQuc2NhbGVzLmJ1ZmZlciwKICAgICAgICAgIGNvbG9yczogc3BsYXQuY29sb3JzLmJ1ZmZlciwKICAgICAgICAgIHNlbGVjdGlvbjogc3BsYXQuc2VsZWN0aW9uLmJ1ZmZlciwKICAgICAgfTsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7IHJlc3BvbnNlOiByZXNwb25zZSB9LCBbCiAgICAgICAgICByZXNwb25zZS5kYXRhLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkUG9zaXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkUm90YXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkU2NhbGVzLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLnBvc2l0aW9ucywKICAgICAgICAgIHJlc3BvbnNlLnJvdGF0aW9ucywKICAgICAgICAgIHJlc3BvbnNlLnNjYWxlcywKICAgICAgICAgIHJlc3BvbnNlLmNvbG9ycywKICAgICAgICAgIHJlc3BvbnNlLnNlbGVjdGlvbiwKICAgICAgXSk7CiAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKICB9OwogIGNvbnN0IHBhY2tUaHJvdHRsZWQgPSAoKSA9PiB7CiAgICAgIGlmICh1cGRhdGVRdWV1ZS5sZW5ndGggPT09IDApCiAgICAgICAgICByZXR1cm47CiAgICAgIGlmICghcnVubmluZykgewogICAgICAgICAgcnVubmluZyA9IHRydWU7CiAgICAgICAgICBjb25zdCBzcGxhdCA9IHVwZGF0ZVF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICBwYWNrKHNwbGF0KTsKICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKICAgICAgICAgICAgICBwYWNrVGhyb3R0bGVkKCk7CiAgICAgICAgICB9LCAwKTsKICAgICAgfQogIH07CiAgc2VsZi5vbm1lc3NhZ2UgPSAoZSkgPT4gewogICAgICBpZiAoZS5kYXRhLnNwbGF0KSB7CiAgICAgICAgICBjb25zdCBzcGxhdCA9IGUuZGF0YS5zcGxhdDsKICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBleGlzdGluZ10gb2YgdXBkYXRlUXVldWUuZW50cmllcygpKSB7CiAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nLm9mZnNldCA9PT0gc3BsYXQub2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgIHVwZGF0ZVF1ZXVlW2luZGV4XSA9IHNwbGF0OwogICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgdXBkYXRlUXVldWUucHVzaChzcGxhdCk7CiAgICAgICAgICBwYWNrVGhyb3R0bGVkKCk7CiAgICAgIH0KICB9OwoKfSkoKTsKCg==",null,!1),X=async function(t={}){var F,U,l,n=t,Q=new Promise(((t,l)=>{F=t,U=l})),e=Object.assign({},n),d="";d=(d=self.location.href).startsWith("blob:")?"":d.slice(0,d.replace(/[?#].*/,"").lastIndexOf("/")+1),l=t=>{var F=new XMLHttpRequest;return F.open("GET",t,!1),F.responseType="arraybuffer",F.send(null),new Uint8Array(F.response)},n.print||console.log.bind(console);var A=n.printErr||console.error.bind(console);Object.assign(n,e),e=null,n.arguments&&n.arguments,n.thisProgram&&n.thisProgram;var B,a,i,V,Z,R,c,s,o,r,h,W=n.wasmBinary,I=!1;function m(){var t=B.buffer;n.HEAP8=a=new Int8Array(t),n.HEAP16=V=new Int16Array(t),n.HEAPU8=i=new Uint8Array(t),n.HEAPU16=Z=new Uint16Array(t),n.HEAP32=R=new Int32Array(t),n.HEAPU32=c=new Uint32Array(t),n.HEAPF32=s=new Float32Array(t),n.HEAPF64=h=new Float64Array(t),n.HEAP64=o=new BigInt64Array(t),n.HEAPU64=r=new BigUint64Array(t)}var b=0,J=null;function g(t){n.onAbort?.(t),A(t="Aborted("+t+")"),I=!0,t+=". Build with -sASSERTIONS for more info.";var F=new WebAssembly.RuntimeError(t);throw U(F),F}var C="data:application/octet-stream;base64,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AkcNASABQQE6ADYPCyAAKAIIIgAgASACIAMgBCAAKAIAKAIYEQIACwsxACAAIAEoAghBABALBEAgASACIAMQFA8LIAAoAggiACABIAIgAyAAKAIAKAIcEQAACxgAIAAgASgCCEEAEAsEQCABIAIgAxAUCwulBQEGfyMAQdAAayIEJAACQAJ/QQEgACABQQAQCw0AGkEAIAFFDQAaIwBBEGsiBiQAIAYgASgCACIDQQhrKAIAIgU2AgwgBiABIAVqNgIEIAYgA0EEaygCADYCCCAGKAIIIgNByAhBABALIQUgBigCBCEHAkAgBQRAIAYoAgwhASMAQUBqIgMkACADQUBrJABBACAHIAEbIQMMAQsgAyEFIwBBQGoiAyQAIAEgB04EQCADQgA3AhwgA0IANwIkIANCADcCLCADQgA3AhQgA0EANgIQIANByAg2AgwgAyAFNgIEIANBADYCPCADQoGAgICAgICAATcCNCADIAE2AgggBSADQQRqIAcgB0EBQQAgBSgCACgCFBEDACABQQAgAygCHBshCAsgA0FAayQAIAgiAw0AIwBBQGoiAyQAIANBADYCECADQZgINgIMIAMgATYCCCADQcgINgIEQQAhASADQRRqQQBBJ/wLACADQQA2AjwgA0EBOgA7IAUgA0EEaiAHQQFBACAFKAIAKAIYEQIAAkACQAJAIAMoAigOAgABAgsgAygCGEEAIAMoAiRBAUYbQQAgAygCIEEBRhtBACADKAIsQQFGGyEBDAELIAMoAhxBAUcEQCADKAIsDQEgAygCIEEBRw0BIAMoAiRBAUcNAQsgAygCFCEBCyADQUBrJAAgASEDCyAGQRBqJABBACADRQ0AGiACKAIAIgFFDQEgBEEYakEAQTj8CwAgBEEBOgBLIARBfzYCICAEIAA2AhwgBCADNgIUIARBATYCRCADIARBFGogAUEBIAMoAgAoAhwRAAAgBCgCLCIAQQFGBEAgAiAEKAIkNgIACyAAQQFGCyAEQdAAaiQADwsgBEHPCjYCCCAEQeUDNgIEIARBuQk2AgAQCQALCgAgACABQQAQCwsEACAACwvbEQIAQYAIC8oRBAkAAAgEAABTdDl0eXBlX2luZm8AAAAALAkAACQEAAAABAAATjEwX19jeHhhYml2MTE2X19zaGltX3R5cGVfaW5mb0UAAAAALAkAAFQEAAAYBAAATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAHVuc2lnbmVkIHNob3J0AHVuc2lnbmVkIGludABmbG9hdAB1aW50NjRfdAAlczolZDogJXMAdW5zaWduZWQgY2hhcgAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAYm9vbAB1bnNpZ25lZCBsb25nAHN0ZDo6d3N0cmluZwBzdGQ6OnN0cmluZwBzdGQ6OnUxNnN0cmluZwBzdGQ6OnUzMnN0cmluZwBkb3VibGUAdm9pZABjYXRjaGluZyBhIGNsYXNzIHdpdGhvdXQgYW4gb2JqZWN0PwBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZG91YmxlPgAAAAAAAAAAFAgAAAEAAAACAAAAAwAAAAQAAAAFAAAALAkAACAIAAAYBAAATjEwX19jeHhhYml2MTIzX19mdW5kYW1lbnRhbF90eXBlX2luZm9FAAAIAABQCAAAdgAAAAAIAABcCAAAYgAAAAAIAABoCAAAYwAAAAAIAAB0CAAAaAAAAAAIAACACAAAYQAAAAAIAACMCAAAcwAAAAAIAACYCAAAdAAAAAAIAACkCAAAaQAAAAAIAACwCAAAagAAAAAIAAC8CAAAbAAAAAAIAADICAAAbQAAAAAIAADUCAAAeAAAAAAIAADgCAAAeQAAAAAIAADsCAAAZgAAAAAIAAD4CAAAZAAAAAAAAABIBAAAAQAAAAYAAAADAAAABAAAAAcAAAAIAAAACQAAAAoAAAAAAAAATAkAAAEAAAALAAAAAwAAAAQAAAAHAAAADAAAAA0AAAAOAAAALAkAAFgJAABIBAAATjEwX19jeHhhYml2MTIwX19zaV9jbGFzc190eXBlX2luZm9FAAAAAAQJAACICQAATlN0M19fMjEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUUAAAQJAADQCQAATlN0M19fMjEyYmFzaWNfc3RyaW5nSXdOU18xMWNoYXJfdHJhaXRzSXdFRU5TXzlhbGxvY2F0b3JJd0VFRUUAAAQJAAAYCgAATlN0M19fMjEyYmFzaWNfc3RyaW5nSURzTlNfMTFjaGFyX3RyYWl0c0lEc0VFTlNfOWFsbG9jYXRvcklEc0VFRUUAAAAECQAAZAoAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEaU5TXzExY2hhcl90cmFpdHNJRGlFRU5TXzlhbGxvY2F0b3JJRGlFRUVFAAAABAkAALAKAABOMTBlbXNjcmlwdGVuM3ZhbEUAAAQJAADMCgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJY0VFAAAECQAA9AoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWFFRQAABAkAABwLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0loRUUAAAQJAABECwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJc0VFAAAECQAAbAsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXRFRQAABAkAAJQLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lpRUUAAAQJAAC8CwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJakVFAAAECQAA5AsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWxFRQAABAkAAAwMAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0ltRUUAAAQJAAA0DAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJeEVFAAAECQAAXAwAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXlFRQAABAkAAIQMAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lmRUUAAAQJAACsDAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZEVFAEHMGQsD0A4B";async function N(t){return function(t){if(t==C&&W)return new Uint8Array(W);var F=T(t);if(F)return F;if(l)return l(t);throw"both async and sync fetching of the wasm failed"}(t)}async function G(t,F,U){return async function(t,F){try{var U=await N(t);return await WebAssembly.instantiate(U,F)}catch(t){A(`failed to asynchronously prepare wasm: ${t}`),g(t)}}(F,U)}var X=t=>{for(;t.length>0;)t.shift()(n)},E=[],p=t=>E.unshift(t),y=[],S=t=>y.unshift(t);n.noExitRuntime;var k,u,Y="data:application/octet-stream;base64,",T=t=>{if((t=>t.startsWith(Y))(t))return(t=>{for(var F,U,l=0,n=0,Q=t.length,e=new Uint8Array((3*Q>>2)-("="==t[Q-2])-("="==t[Q-1]));l<Q;l+=4,n+=3)F=Bt[t.charCodeAt(l+1)],U=Bt[t.charCodeAt(l+2)],e[n]=Bt[t.charCodeAt(l)]<<2|F>>4,e[n+1]=F<<4|U>>2,e[n+2]=U<<6|Bt[t.charCodeAt(l+3)];return e})(t.slice(Y.length))},x=t=>{for(var F="",U=t;i[U];)F+=k[i[U++]];return F},H={},D={},f=t=>{throw new u(t)};function w(t,F,U={}){return function(t,F,U={}){var l=F.name;if(t||f(`type "${l}" must have a positive integer typeid pointer`),D.hasOwnProperty(t)){if(U.ignoreDuplicateRegistrations)return;f(`Cannot register type '${l}' twice`)}if(D[t]=F,H.hasOwnProperty(t)){var n=H[t];delete H[t],n.forEach((t=>t()))}}(t,F,U)}var v=(t,F,U)=>{switch(F){case 1:return U?t=>a[t]:t=>i[t];case 2:return U?t=>V[t>>1]:t=>Z[t>>1];case 4:return U?t=>R[t>>2]:t=>c[t>>2];case 8:return U?t=>o[t>>3]:t=>r[t>>3];default:throw new TypeError(`invalid integer width (${F}): ${t}`)}},z=8,M=[],j=[],K=()=>j.length/2-5-M.length,O=t=>(t||f("Cannot use deleted val. handle = "+t),j[t]),L=t=>{switch(t){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{const F=M.pop()||j.length;return j[F]=t,j[F+1]=1,F}}};function P(t){return this.fromWireType(c[t>>2])}for(var _={name:"emscripten::val",fromWireType:t=>{var F=O(t);return(t=>{t>9&&0==--j[t+1]&&(j[t]=void 0,M.push(t))})(t),F},toWireType:(t,F)=>L(F),argPackAdvance:z,readValueFromPointer:P,destructorFunction:null},q=(t,F)=>{switch(F){case 4:return function(t){return this.fromWireType(s[t>>2])};case 8:return function(t){return this.fromWireType(h[t>>3])};default:throw new TypeError(`invalid float width (${F}): ${t}`)}},$="undefined"!=typeof TextDecoder?new TextDecoder:void 0,tt=(t,F)=>t?((t,F=0,U=NaN)=>{for(var l=F+U,n=F;t[n]&&!(n>=l);)++n;if(n-F>16&&t.buffer&&$)return $.decode(t.subarray(F,n));for(var Q="";F<n;){var e=t[F++];if(128&e){var d=63&t[F++];if(192!=(224&e)){var A=63&t[F++];if((e=224==(240&e)?(15&e)<<12|d<<6|A:(7&e)<<18|d<<12|A<<6|63&t[F++])<65536)Q+=String.fromCharCode(e);else{var B=e-65536;Q+=String.fromCharCode(55296|B>>10,56320|1023&B)}}else Q+=String.fromCharCode((31&e)<<6|d)}else Q+=String.fromCharCode(e)}return Q})(i,t,F):"",Ft="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0,Ut=(t,F)=>{for(var U=t,l=U>>1,n=l+F/2;!(l>=n)&&Z[l];)++l;if((U=l<<1)-t>32&&Ft)return Ft.decode(i.subarray(t,U));for(var Q="",e=0;!(e>=F/2);++e){var d=V[t+2*e>>1];if(0==d)break;Q+=String.fromCharCode(d)}return Q},lt=(t,F,U)=>{if(U??=2147483647,U<2)return 0;for(var l=F,n=(U-=2)<2*t.length?U/2:t.length,Q=0;Q<n;++Q){var e=t.charCodeAt(Q);V[F>>1]=e,F+=2}return V[F>>1]=0,F-l},nt=t=>2*t.length,Qt=(t,F)=>{for(var U=0,l="";!(U>=F/4);){var n=R[t+4*U>>2];if(0==n)break;if(++U,n>=65536){var Q=n-65536;l+=String.fromCharCode(55296|Q>>10,56320|1023&Q)}else l+=String.fromCharCode(n)}return l},et=(t,F,U)=>{if(U??=2147483647,U<4)return 0;for(var l=F,n=l+U-4,Q=0;Q<t.length;++Q){var e=t.charCodeAt(Q);if(e>=55296&&e<=57343&&(e=65536+((1023&e)<<10)|1023&t.charCodeAt(++Q)),R[F>>2]=e,(F+=4)+4>n)break}return R[F>>2]=0,F-l},dt=t=>{for(var F=0,U=0;U<t.length;++U){var l=t.charCodeAt(U);l>=55296&&l<=57343&&++U,F+=4}return F},At=t=>{var F=(t-B.buffer.byteLength+65535)/65536|0;try{return B.grow(F),m(),1}catch(t){}},Bt=new Uint8Array(123),at=25;at>=0;--at)Bt[48+at]=52+at,Bt[65+at]=at,Bt[97+at]=26+at;Bt[43]=62,Bt[47]=63,(()=>{for(var t=new Array(256),F=0;F<256;++F)t[F]=String.fromCharCode(F);k=t})(),u=n.BindingError=class extends Error{constructor(t){super(t),this.name="BindingError"}},n.InternalError=class extends Error{constructor(t){super(t),this.name="InternalError"}},j.push(0,1,void 0,1,null,1,!0,1,!1,1),n.count_emval_handles=K;var it={j:()=>g(""),e:(t,F,U,l,n)=>{var Q=-1!=(F=x(F)).indexOf("u");w(t,{name:F,fromWireType:t=>t,toWireType:function(t,F){if("bigint"!=typeof F&&"number"!=typeof F)throw new TypeError(`Cannot convert "${(t=>{if(null===t)return"null";var F=typeof t;return"object"===F||"array"===F||"function"===F?t.toString():""+t})(F)}" to ${this.name}`);return"number"==typeof F&&(F=BigInt(F)),F},argPackAdvance:z,readValueFromPointer:v(F,U,!Q),destructorFunction:null})},h:(t,F,U,l)=>{w(t,{name:F=x(F),fromWireType:function(t){return!!t},toWireType:function(t,F){return F?U:l},argPackAdvance:z,readValueFromPointer:function(t){return this.fromWireType(i[t])},destructorFunction:null})},f:t=>w(t,_),d:(t,F,U)=>{w(t,{name:F=x(F),fromWireType:t=>t,toWireType:(t,F)=>F,argPackAdvance:z,readValueFromPointer:q(F,U),destructorFunction:null})},b:(t,F,U,l,n)=>{F=x(F);var Q=t=>t;if(0===l){var e=32-8*U;Q=t=>t<<e>>>e}var d=F.includes("unsigned");w(t,{name:F,fromWireType:Q,toWireType:d?function(t,F){return this.name,F>>>0}:function(t,F){return this.name,F},argPackAdvance:z,readValueFromPointer:v(F,U,0!==l),destructorFunction:null})},a:(t,F,U)=>{var l=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array][F];function n(t){var F=c[t>>2],U=c[t+4>>2];return new l(a.buffer,U,F)}w(t,{name:U=x(U),fromWireType:n,argPackAdvance:z,readValueFromPointer:n},{ignoreDuplicateRegistrations:!0})},g:(t,F)=>{w(t,{name:F=x(F),fromWireType(t){for(var F,U=c[t>>2],l=t+4,n=l,Q=0;Q<=U;++Q){var e=l+Q;if(Q==U||0==i[e]){var d=tt(n,e-n);void 0===F?F=d:(F+=String.fromCharCode(0),F+=d),n=e+1}}return Rt(t),F},toWireType(t,F){var U;F instanceof ArrayBuffer&&(F=new Uint8Array(F));var l="string"==typeof F;l||F instanceof Uint8Array||F instanceof Uint8ClampedArray||F instanceof Int8Array||f("Cannot pass non-string to std::string"),U=l?(t=>{for(var F=0,U=0;U<t.length;++U){var l=t.charCodeAt(U);l<=127?F++:l<=2047?F+=2:l>=55296&&l<=57343?(F+=4,++U):F+=3}return F})(F):F.length;var n=Zt(4+U+1),Q=n+4;if(c[n>>2]=U,l)((t,F,U,l)=>{if(!(l>0))return 0;for(var n=U+l-1,Q=0;Q<t.length;++Q){var e=t.charCodeAt(Q);if(e>=55296&&e<=57343&&(e=65536+((1023&e)<<10)|1023&t.charCodeAt(++Q)),e<=127){if(U>=n)break;F[U++]=e}else if(e<=2047){if(U+1>=n)break;F[U++]=192|e>>6,F[U++]=128|63&e}else if(e<=65535){if(U+2>=n)break;F[U++]=224|e>>12,F[U++]=128|e>>6&63,F[U++]=128|63&e}else{if(U+3>=n)break;F[U++]=240|e>>18,F[U++]=128|e>>12&63,F[U++]=128|e>>6&63,F[U++]=128|63&e}}F[U]=0})(F,i,Q,U+1);else if(l)for(var e=0;e<U;++e){var d=F.charCodeAt(e);d>255&&(Rt(n),f("String has UTF-16 code units that do not fit in 8 bits")),i[Q+e]=d}else for(e=0;e<U;++e)i[Q+e]=F[e];return null!==t&&t.push(Rt,n),n},argPackAdvance:z,readValueFromPointer:P,destructorFunction(t){Rt(t)}})},c:(t,F,U)=>{var l,n,Q,e;U=x(U),2===F?(l=Ut,n=lt,e=nt,Q=t=>Z[t>>1]):4===F&&(l=Qt,n=et,e=dt,Q=t=>c[t>>2]),w(t,{name:U,fromWireType:t=>{for(var U,n=c[t>>2],e=t+4,d=0;d<=n;++d){var A=t+4+d*F;if(d==n||0==Q(A)){var B=l(e,A-e);void 0===U?U=B:(U+=String.fromCharCode(0),U+=B),e=A+F}}return Rt(t),U},toWireType:(t,l)=>{"string"!=typeof l&&f(`Cannot pass non-string to C++ string type ${U}`);var Q=e(l),d=Zt(4+Q+F);return c[d>>2]=Q/F,n(l,d+4,Q+F),null!==t&&t.push(Rt,d),d},argPackAdvance:z,readValueFromPointer:P,destructorFunction(t){Rt(t)}})},i:(t,F)=>{w(t,{isVoid:!0,name:F=x(F),argPackAdvance:0,fromWireType:()=>{},toWireType:(t,F)=>{}})},k:t=>{var F,U,l=i.length,n=2147483648;if((t>>>=0)>n)return!1;for(var Q=1;Q<=4;Q*=2){var e=l*(1+.2/Q);e=Math.min(e,t+100663296);var d=Math.min(n,(F=Math.max(t,e),U=65536,Math.ceil(F/U)*U));if(At(d))return!0}return!1}},Vt=await async function(){function t(t,F){return Vt=t.exports,B=Vt.l,m(),function(t){if(b--,n.monitorRunDependencies?.(b),0==b&&J){var F=J;J=null,F()}}(),Vt}b++,n.monitorRunDependencies?.(b);var F={a:it};if(n.instantiateWasm)return new Promise(((U,l)=>{n.instantiateWasm(F,((F,l)=>{t(F),U(F.exports)}))}));try{var l=function(F){return t(F.instance)}(await G(0,C,F));return l}catch(t){return U(t),Promise.reject(t)}}();Vt.m,n._pack=Vt.n;var Zt=n._malloc=Vt.o,Rt=n._free=Vt.p;if(n.preInit)for("function"==typeof n.preInit&&(n.preInit=[n.preInit]);n.preInit.length>0;)n.preInit.pop()();return function t(){function U(){n.calledRun=!0,I||(Vt.m(),F(n),n.onRuntimeInitialized?.(),function(){if(n.postRun)for("function"==typeof n.postRun&&(n.postRun=[n.postRun]);n.postRun.length;)p(n.postRun.shift());X(E)}())}b>0?J=t:(function(){if(n.preRun)for("function"==typeof n.preRun&&(n.preRun=[n.preRun]);n.preRun.length;)S(n.preRun.shift());X(y)}(),b>0?J=t:n.setStatus?(n.setStatus("Running..."),setTimeout((()=>{setTimeout((()=>n.setStatus("")),1),U()}),1)):U())}(),Q};class E{constructor(t){this.dataChanged=!1,this.transformsChanged=!1,this.colorTransformsChanged=!1,this._updating=new Set,this._dirty=new Set;let F=0,U=0;this._splatIndices=new Map,this._offsets=new Map;const n=new Map;for(const l of t.objects)l instanceof Z&&(this._splatIndices.set(l,U),this._offsets.set(l,F),n.set(F,l),F+=l.data.vertexCount,U++);this._vertexCount=F,this._width=2048,this._height=Math.ceil(2*this.vertexCount/this.width),this._data=new Uint32Array(this.width*this.height*4),this._transformsWidth=5,this._transformsHeight=n.size,this._transforms=new Float32Array(this._transformsWidth*this._transformsHeight*4),this._transformIndicesWidth=1024,this._transformIndicesHeight=Math.ceil(this.vertexCount/this._transformIndicesWidth),this._transformIndices=new Uint32Array(this._transformIndicesWidth*this._transformIndicesHeight),this._colorTransformsWidth=4,this._colorTransformsHeight=64,this._colorTransforms=new Float32Array(this._colorTransformsWidth*this._colorTransformsHeight*4),this._colorTransforms.fill(0),this._colorTransforms[0]=1,this._colorTransforms[5]=1,this._colorTransforms[10]=1,this._colorTransforms[15]=1,this._colorTransformIndicesWidth=1024,this._colorTransformIndicesHeight=Math.ceil(this.vertexCount/this._colorTransformIndicesWidth),this._colorTransformIndices=new Uint32Array(this._colorTransformIndicesWidth*this._colorTransformIndicesHeight),this.colorTransformIndices.fill(0),this._positions=new Float32Array(3*this.vertexCount),this._rotations=new Float32Array(4*this.vertexCount),this._scales=new Float32Array(3*this.vertexCount),this._worker=new G;const Q=t=>{const F=this._splatIndices.get(t);this._transforms.set(t.transform.buffer,20*F),this._transforms[20*F+16]=t.selected?1:0,t.positionChanged=!1,t.rotationChanged=!1,t.scaleChanged=!1,t.selectedChanged=!1,this.transformsChanged=!0},e=()=>{let t=!1;for(const F of this._splatIndices.keys())if(F.colorTransformChanged){t=!0;break}if(!t)return;const F=[new l];this._colorTransformIndices.fill(0);let U=1;for(const t of this._splatIndices.keys()){const l=this._offsets.get(t);for(const l of t.colorTransforms)F.includes(l)||(F.push(l),U++);for(const F of t.colorTransformsMap.keys()){const n=t.colorTransformsMap.get(F);this._colorTransformIndices[F+l]=n+U-1}t.colorTransformChanged=!1}for(let t=0;t<F.length;t++){const U=F[t];this._colorTransforms.set(U.buffer,16*t)}this.colorTransformsChanged=!0};let d;this._worker.onmessage=t=>{if(t.data.response){const F=t.data.response,U=n.get(F.offset);Q(U),e();const l=this._splatIndices.get(U);for(let t=0;t<U.data.vertexCount;t++)this._transformIndices[F.offset+t]=l;this._data.set(F.data,8*F.offset),U.data.reattach(F.positions,F.rotations,F.scales,F.colors,F.selection),this._positions.set(F.worldPositions,3*F.offset),this._rotations.set(F.worldRotations,4*F.offset),this._scales.set(F.worldScales,3*F.offset),this._updating.delete(U),U.selectedChanged=!1,this.dataChanged=!0}},async function(){d=await X()}();const A=t=>{if(!d)return void async function(){for(;!d;)await new Promise((t=>setTimeout(t,0)))}().then((()=>{A(t)}));Q(t);const F=d._malloc(3*t.data.vertexCount*4),U=d._malloc(4*t.data.vertexCount*4),l=d._malloc(3*t.data.vertexCount*4),n=d._malloc(4*t.data.vertexCount),e=d._malloc(t.data.vertexCount),B=d._malloc(8*t.data.vertexCount*4),a=d._malloc(3*t.data.vertexCount*4),i=d._malloc(4*t.data.vertexCount*4),V=d._malloc(3*t.data.vertexCount*4);d.HEAPF32.set(t.data.positions,F/4),d.HEAPF32.set(t.data.rotations,U/4),d.HEAPF32.set(t.data.scales,l/4),d.HEAPU8.set(t.data.colors,n),d.HEAPU8.set(t.data.selection,e),d._pack(t.selected,t.data.vertexCount,F,U,l,n,e,B,a,i,V);const Z=new Uint32Array(d.HEAPU32.buffer,B,8*t.data.vertexCount),R=new Float32Array(d.HEAPF32.buffer,a,3*t.data.vertexCount),c=new Float32Array(d.HEAPF32.buffer,i,4*t.data.vertexCount),s=new Float32Array(d.HEAPF32.buffer,V,3*t.data.vertexCount),o=this._splatIndices.get(t),r=this._offsets.get(t);for(let F=0;F<t.data.vertexCount;F++)this._transformIndices[r+F]=o;this._data.set(Z,8*r),this._positions.set(R,3*r),this._rotations.set(c,4*r),this._scales.set(s,3*r),d._free(F),d._free(U),d._free(l),d._free(n),d._free(e),d._free(B),d._free(a),d._free(i),d._free(V),this.dataChanged=!0,this.colorTransformsChanged=!0},B=t=>{if((t.positionChanged||t.rotationChanged||t.scaleChanged||t.selectedChanged)&&Q(t),t.colorTransformChanged&&e(),!t.data.changed||t.data.detached)return;const F={position:new Float32Array(t.position.flat()),rotation:new Float32Array(t.rotation.flat()),scale:new Float32Array(t.scale.flat()),selected:t.selected,vertexCount:t.data.vertexCount,positions:t.data.positions,rotations:t.data.rotations,scales:t.data.scales,colors:t.data.colors,selection:t.data.selection,offset:this._offsets.get(t)};this._worker.postMessage({splat:F},[F.position.buffer,F.rotation.buffer,F.scale.buffer,F.positions.buffer,F.rotations.buffer,F.scales.buffer,F.colors.buffer,F.selection.buffer]),this._updating.add(t),t.data.detached=!0};this.getSplat=t=>{let F=null;for(const[U,l]of this._offsets){if(!(t>=l))break;F=U}return F},this.getLocalIndex=(t,F)=>F-this._offsets.get(t),this.markDirty=t=>{this._dirty.add(t)},this.rebuild=()=>{for(const t of this._dirty)B(t);this._dirty.clear()},this.dispose=()=>{this._worker.terminate()};for(const t of this._splatIndices.keys())A(t);e()}get offsets(){return this._offsets}get data(){return this._data}get width(){return this._width}get height(){return this._height}get transforms(){return this._transforms}get transformsWidth(){return this._transformsWidth}get transformsHeight(){return this._transformsHeight}get transformIndices(){return this._transformIndices}get transformIndicesWidth(){return this._transformIndicesWidth}get transformIndicesHeight(){return this._transformIndicesHeight}get colorTransforms(){return this._colorTransforms}get colorTransformsWidth(){return this._colorTransformsWidth}get colorTransformsHeight(){return this._colorTransformsHeight}get colorTransformIndices(){return this._colorTransformIndices}get colorTransformIndicesWidth(){return this._colorTransformIndicesWidth}get colorTransformIndicesHeight(){return this._colorTransformIndicesHeight}get positions(){return this._positions}get rotations(){return this._rotations}get scales(){return this._scales}get vertexCount(){return this._vertexCount}get needsRebuild(){return this._dirty.size>0}get updating(){return this._updating.size>0}}class p{constructor(t=0,F=0,U=0,l=255){this.r=t,this.g=F,this.b=U,this.a=l}flat(){return[this.r,this.g,this.b,this.a]}flatNorm(){return[this.r/255,this.g/255,this.b/255,this.a/255]}toHexString(){return"#"+this.flat().map((t=>t.toString(16).padStart(2,"0"))).join("")}toString(){return`[${this.flat().join(", ")}]`}}class y extends N{constructor(t,F){super(t,F),this._outlineThickness=10,this._outlineColor=new p(255,165,0,255),this._renderData=null,this._depthIndex=new Uint32Array,this._splatTexture=null,this._worker=null;const U=t.canvas,l=t.gl;let n,Q,e,d,A,B,a,i,V,R,c,s,o,r,h,W,I,m,b;this._resize=()=>{this._camera&&(this._camera.data.setSize(U.width,U.height),this._camera.update(),n=l.getUniformLocation(this.program,"projection"),l.uniformMatrix4fv(n,!1,this._camera.data.projectionMatrix.buffer),Q=l.getUniformLocation(this.program,"viewport"),l.uniform2fv(Q,new Float32Array([U.width,U.height])))};const J=()=>{this._worker=new C,this._worker.onmessage=t=>{if(t.data.depthIndex){const{depthIndex:F}=t.data;this._depthIndex=F,l.bindBuffer(l.ARRAY_BUFFER,b),l.bufferData(l.ARRAY_BUFFER,F,l.STATIC_DRAW)}}};this._initialize=()=>{if(this._scene&&this._camera){this._resize(),this._scene.addEventListener("objectAdded",g),this._scene.addEventListener("objectRemoved",N);for(const t of this._scene.objects)t instanceof Z&&t.addEventListener("objectChanged",G);this._renderData=new E(this._scene),e=l.getUniformLocation(this.program,"focal"),l.uniform2fv(e,new Float32Array([this._camera.data.fx,this._camera.data.fy])),d=l.getUniformLocation(this.program,"view"),l.uniformMatrix4fv(d,!1,this._camera.data.viewMatrix.buffer),R=l.getUniformLocation(this.program,"outlineThickness"),l.uniform1f(R,this.outlineThickness),c=l.getUniformLocation(this.program,"outlineColor"),l.uniform4fv(c,new Float32Array(this.outlineColor.flatNorm())),this._splatTexture=l.createTexture(),A=l.getUniformLocation(this.program,"u_texture"),l.uniform1i(A,0),r=l.createTexture(),B=l.getUniformLocation(this.program,"u_transforms"),l.uniform1i(B,1),h=l.createTexture(),a=l.getUniformLocation(this.program,"u_transformIndices"),l.uniform1i(a,2),W=l.createTexture(),i=l.getUniformLocation(this.program,"u_colorTransforms"),l.uniform1i(i,3),I=l.createTexture(),V=l.getUniformLocation(this.program,"u_colorTransformIndices"),l.uniform1i(V,4),m=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,m),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-2,-2,2,-2,2,2,-2,2]),l.STATIC_DRAW),s=l.getAttribLocation(this.program,"position"),l.enableVertexAttribArray(s),l.vertexAttribPointer(s,2,l.FLOAT,!1,0,0),b=l.createBuffer(),o=l.getAttribLocation(this.program,"index"),l.enableVertexAttribArray(o),l.bindBuffer(l.ARRAY_BUFFER,b),J()}else console.error("Cannot render without scene and camera")};const g=t=>{const F=t;F.object instanceof Z&&F.object.addEventListener("objectChanged",G),X()},N=t=>{const F=t;F.object instanceof Z&&F.object.removeEventListener("objectChanged",G),X()},G=t=>{const F=t;F.object instanceof Z&&this._renderData&&this._renderData.markDirty(F.object)},X=()=>{var t,F;null===(t=this._renderData)||void 0===t||t.dispose(),this._renderData=new E(this._scene),null===(F=this._worker)||void 0===F||F.terminate(),J()};this._render=()=>{var t,F;if(this._scene&&this._camera&&this.renderData){if(this.renderData.needsRebuild&&this.renderData.rebuild(),this.renderData.dataChanged||this.renderData.transformsChanged||this.renderData.colorTransformsChanged){this.renderData.dataChanged&&(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,this.splatTexture),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32UI,this.renderData.width,this.renderData.height,0,l.RGBA_INTEGER,l.UNSIGNED_INT,this.renderData.data)),this.renderData.transformsChanged&&(l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,r),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32F,this.renderData.transformsWidth,this.renderData.transformsHeight,0,l.RGBA,l.FLOAT,this.renderData.transforms),l.activeTexture(l.TEXTURE2),l.bindTexture(l.TEXTURE_2D,h),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.R32UI,this.renderData.transformIndicesWidth,this.renderData.transformIndicesHeight,0,l.RED_INTEGER,l.UNSIGNED_INT,this.renderData.transformIndices)),this.renderData.colorTransformsChanged&&(l.activeTexture(l.TEXTURE3),l.bindTexture(l.TEXTURE_2D,W),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32F,this.renderData.colorTransformsWidth,this.renderData.colorTransformsHeight,0,l.RGBA,l.FLOAT,this.renderData.colorTransforms),l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,I),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.R32UI,this.renderData.colorTransformIndicesWidth,this.renderData.colorTransformIndicesHeight,0,l.RED_INTEGER,l.UNSIGNED_INT,this.renderData.colorTransformIndices));const F=new Float32Array(this.renderData.positions.slice().buffer),U=new Float32Array(this.renderData.transforms.slice().buffer),n=new Uint32Array(this.renderData.transformIndices.slice().buffer);null===(t=this._worker)||void 0===t||t.postMessage({sortData:{positions:F,transforms:U,transformIndices:n,vertexCount:this.renderData.vertexCount}},[F.buffer,U.buffer,n.buffer]),this.renderData.dataChanged=!1,this.renderData.transformsChanged=!1,this.renderData.colorTransformsChanged=!1}this._camera.update(),null===(F=this._worker)||void 0===F||F.postMessage({viewProj:this._camera.data.viewProj.buffer}),l.viewport(0,0,U.width,U.height),l.clearColor(0,0,0,0),l.clear(l.COLOR_BUFFER_BIT),l.disable(l.DEPTH_TEST),l.enable(l.BLEND),l.blendFuncSeparate(l.ONE_MINUS_DST_ALPHA,l.ONE,l.ONE_MINUS_DST_ALPHA,l.ONE),l.blendEquationSeparate(l.FUNC_ADD,l.FUNC_ADD),l.uniformMatrix4fv(n,!1,this._camera.data.projectionMatrix.buffer),l.uniformMatrix4fv(d,!1,this._camera.data.viewMatrix.buffer),l.bindBuffer(l.ARRAY_BUFFER,m),l.vertexAttribPointer(s,2,l.FLOAT,!1,0,0),l.bindBuffer(l.ARRAY_BUFFER,b),l.bufferData(l.ARRAY_BUFFER,this.depthIndex,l.STATIC_DRAW),l.vertexAttribIPointer(o,1,l.INT,0,0),l.vertexAttribDivisor(o,1),l.drawArraysInstanced(l.TRIANGLE_FAN,0,4,this.depthIndex.length)}else console.error("Cannot render without scene and camera")},this._dispose=()=>{var t;if(this._scene&&this._camera&&this.renderData){this._scene.removeEventListener("objectAdded",g),this._scene.removeEventListener("objectRemoved",N);for(const t of this._scene.objects)t instanceof Z&&t.removeEventListener("objectChanged",G);null===(t=this._worker)||void 0===t||t.terminate(),this.renderData.dispose(),l.deleteTexture(this.splatTexture),l.deleteTexture(r),l.deleteTexture(h),l.deleteBuffer(b),l.deleteBuffer(m)}else console.error("Cannot dispose without scene and camera")},this._setOutlineThickness=t=>{this._outlineThickness=t,this._initialized&&l.uniform1f(R,t)},this._setOutlineColor=t=>{this._outlineColor=t,this._initialized&&l.uniform4fv(c,new Float32Array(t.flatNorm()))}}get renderData(){return this._renderData}get depthIndex(){return this._depthIndex}get splatTexture(){return this._splatTexture}get outlineThickness(){return this._outlineThickness}set outlineThickness(t){this._setOutlineThickness(t)}get outlineColor(){return this._outlineColor}set outlineColor(t){this._setOutlineColor(t)}get worker(){return this._worker}_getVertexSource(){return"#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform highp usampler2D u_texture;\nuniform highp sampler2D u_transforms;\nuniform highp usampler2D u_transformIndices;\nuniform highp sampler2D u_colorTransforms;\nuniform highp usampler2D u_colorTransformIndices;\nuniform mat4 projection, view;\nuniform vec2 focal;\nuniform vec2 viewport;\n\nuniform bool useDepthFade;\nuniform float depthFade;\n\nin vec2 position;\nin int index;\n\nout vec4 vColor;\nout vec2 vPosition;\nout float vSize;\nout float vSelected;\n\nvoid main () {\n uvec4 cen = texelFetch(u_texture, ivec2((uint(index) & 0x3ffu) << 1, uint(index) >> 10), 0);\n float selected = float((cen.w >> 24) & 0xffu);\n\n uint transformIndex = texelFetch(u_transformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;\n mat4 transform = mat4(\n texelFetch(u_transforms, ivec2(0, transformIndex), 0),\n texelFetch(u_transforms, ivec2(1, transformIndex), 0),\n texelFetch(u_transforms, ivec2(2, transformIndex), 0),\n texelFetch(u_transforms, ivec2(3, transformIndex), 0)\n );\n\n if (selected < 0.5) {\n selected = texelFetch(u_transforms, ivec2(4, transformIndex), 0).x;\n }\n\n mat4 viewTransform = view * transform;\n\n vec4 cam = viewTransform * vec4(uintBitsToFloat(cen.xyz), 1);\n vec4 pos2d = projection * cam;\n\n float clip = 1.2 * pos2d.w;\n if (pos2d.z < -pos2d.w || pos2d.z > pos2d.w || pos2d.x < -clip || pos2d.x > clip || pos2d.y < -clip || pos2d.y > clip) {\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n return;\n }\n\n uvec4 cov = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 1) | 1u, uint(index) >> 10), 0);\n vec2 u1 = unpackHalf2x16(cov.x), u2 = unpackHalf2x16(cov.y), u3 = unpackHalf2x16(cov.z);\n mat3 Vrk = mat3(u1.x, u1.y, u2.x, u1.y, u2.y, u3.x, u2.x, u3.x, u3.y);\n\n mat3 J = mat3(\n focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z), \n 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z), \n 0., 0., 0.\n );\n\n mat3 T = transpose(mat3(viewTransform)) * J;\n mat3 cov2d = transpose(T) * Vrk * T;\n\n //ref: https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/forward.cu#L110-L111\n cov2d[0][0] += 0.3;\n cov2d[1][1] += 0.3;\n\n float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;\n float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));\n float lambda1 = mid + radius, lambda2 = mid - radius;\n\n if (lambda2 < 0.0) return;\n vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));\n vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;\n vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);\n\n uint colorTransformIndex = texelFetch(u_colorTransformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;\n mat4 colorTransform = mat4(\n texelFetch(u_colorTransforms, ivec2(0, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(1, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(2, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(3, colorTransformIndex), 0)\n );\n\n vec4 color = vec4((cov.w) & 0xffu, (cov.w >> 8) & 0xffu, (cov.w >> 16) & 0xffu, (cov.w >> 24) & 0xffu) / 255.0;\n vColor = colorTransform * color;\n\n vPosition = position;\n vSize = length(majorAxis);\n vSelected = selected;\n\n float scalingFactor = 1.0;\n\n if (useDepthFade) {\n float depthNorm = (pos2d.z / pos2d.w + 1.0) / 2.0;\n float near = 0.1; float far = 100.0;\n float normalizedDepth = (2.0 * near) / (far + near - depthNorm * (far - near));\n float start = max(normalizedDepth - 0.1, 0.0);\n float end = min(normalizedDepth + 0.1, 1.0);\n scalingFactor = clamp((depthFade - start) / (end - start), 0.0, 1.0);\n }\n\n vec2 vCenter = vec2(pos2d) / pos2d.w;\n gl_Position = vec4(\n vCenter \n + position.x * majorAxis * scalingFactor / viewport\n + position.y * minorAxis * scalingFactor / viewport, 0.0, 1.0);\n}\n"}_getFragmentSource(){return"#version 300 es\nprecision highp float;\n\nuniform float outlineThickness;\nuniform vec4 outlineColor;\n\nin vec4 vColor;\nin vec2 vPosition;\nin float vSize;\nin float vSelected;\n\nout vec4 fragColor;\n\nvoid main () {\n float A = -dot(vPosition, vPosition);\n\n if (A < -4.0) discard;\n\n if (vSelected < 0.5) {\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n return;\n }\n\n float outlineThreshold = -4.0 + (outlineThickness / vSize);\n\n if (A < outlineThreshold) {\n fragColor = outlineColor;\n } \n else {\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n }\n}\n"}}class S{constructor(t=1){let F,U,l,n,Q=0,e=!1;this.initialize=t=>{if(!(t instanceof y))throw new Error("FadeInPass requires a RenderProgram");Q=t.started?1:0,e=!0,F=t,U=t.renderer.gl,l=U.getUniformLocation(F.program,"useDepthFade"),U.uniform1i(l,1),n=U.getUniformLocation(F.program,"depthFade"),U.uniform1f(n,Q)},this.render=()=>{var d;e&&!(null===(d=F.renderData)||void 0===d?void 0:d.updating)&&(U.useProgram(F.program),Q=Math.min(Q+.01*t,1),Q>=1&&(e=!1,U.uniform1i(l,0)),U.uniform1f(n,Q))}}dispose(){}}class k{constructor(t=null,F=null){this._backgroundColor=new p;const U=t||document.createElement("canvas");t||(U.style.display="block",U.style.boxSizing="border-box",U.style.width="100%",U.style.height="100%",U.style.margin="0",U.style.padding="0",document.body.appendChild(U)),U.style.background=this._backgroundColor.toHexString(),this._canvas=U,this._gl=U.getContext("webgl2",{antialias:!1});const l=F||[];F||l.push(new S),this._renderProgram=new y(this,l);const n=[this._renderProgram];this.resize=()=>{const t=U.clientWidth,F=U.clientHeight;U.width===t&&U.height===F||this.setSize(t,F)},this.setSize=(t,F)=>{U.width=t,U.height=F,this._gl.viewport(0,0,U.width,U.height);for(const t of n)t.resize()},this.render=(t,F)=>{for(const U of n)U.render(t,F)},this.dispose=()=>{for(const t of n)t.dispose()},this.addProgram=t=>{n.push(t)},this.removeProgram=t=>{const F=n.indexOf(t);if(F<0)throw new Error("Program not found");n.splice(F,1)},this.resize()}get canvas(){return this._canvas}get gl(){return this._gl}get renderProgram(){return this._renderProgram}get backgroundColor(){return this._backgroundColor}set backgroundColor(t){this._backgroundColor=t,this._canvas.style.background=t.toHexString()}}class u{constructor(U,l,n=.5,Q=.5,e=5,d=!0,B=new t,a,i,V){this.minAngle=-1/0,this.maxAngle=1/0,this.minAzimuth=-1/0,this.maxAzimuth=1/0,this.minZoom=.1,this.maxZoom=30,this.orbitSpeed=1,this.panSpeed=1,this.zoomSpeed=1,this.dampening=.12,this.setCameraTarget=()=>{};const Z=void 0!==a?a:n,R=void 0!==i?i:Q,c=void 0!==V?V:e;let s=B.clone(),o=s.clone(),r=Z,h=R,W=c,I=Z,m=R,b=c,J=!1,g=!1,C=0,N=0,G=0;const X={};this.setCameraTarget=F=>{const l=F.x-U.position.x,n=F.y-U.position.y,Q=F.z-U.position.z;W=Math.sqrt(l*l+n*n+Q*Q),h=Math.atan2(n,Math.sqrt(l*l+Q*Q)),r=-Math.atan2(l,Q),o=new t(F.x,F.y,F.z)};const E=()=>.1+.9*(W-this.minZoom)/(this.maxZoom-this.minZoom),p=t=>{X[t.code]=!0,"ArrowUp"===t.code&&(X.KeyW=!0),"ArrowDown"===t.code&&(X.KeyS=!0),"ArrowLeft"===t.code&&(X.KeyA=!0),"ArrowRight"===t.code&&(X.KeyD=!0)},y=t=>{X[t.code]=!1,"ArrowUp"===t.code&&(X.KeyW=!1),"ArrowDown"===t.code&&(X.KeyS=!1),"ArrowLeft"===t.code&&(X.KeyA=!1),"ArrowRight"===t.code&&(X.KeyD=!1)},S=t=>{f(t),J=!0,g=2===t.button,N=t.clientX,G=t.clientY,window.addEventListener("mouseup",k)},k=t=>{f(t),J=!1,g=!1,window.removeEventListener("mouseup",k)},u=F=>{if(f(F),!J||!U)return;const l=F.clientX-N,n=F.clientY-G;if(g){const F=E(),Q=-l*this.panSpeed*.01*F,e=-n*this.panSpeed*.01*F,d=A.RotationFromQuaternion(U.rotation).buffer,B=new t(d[0],d[3],d[6]),a=new t(d[1],d[4],d[7]);o=o.add(B.multiply(Q)),o=o.add(a.multiply(e))}else r-=l*this.orbitSpeed*.003,h+=n*this.orbitSpeed*.003,h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180);N=F.clientX,G=F.clientY},Y=t=>{f(t);const F=E();W+=t.deltaY*this.zoomSpeed*.025*F,W=Math.min(Math.max(W,this.minZoom),this.maxZoom)},T=t=>{if(f(t),1===t.touches.length)J=!0,g=!1,N=t.touches[0].clientX,G=t.touches[0].clientY,C=0;else if(2===t.touches.length){J=!0,g=!0,N=(t.touches[0].clientX+t.touches[1].clientX)/2,G=(t.touches[0].clientY+t.touches[1].clientY)/2;const F=t.touches[0].clientX-t.touches[1].clientX,U=t.touches[0].clientY-t.touches[1].clientY;C=Math.sqrt(F*F+U*U)}},x=t=>{f(t),J=!1,g=!1},H=F=>{if(f(F),J&&U)if(g){const l=E(),n=F.touches[0].clientX-F.touches[1].clientX,Q=F.touches[0].clientY-F.touches[1].clientY,e=Math.sqrt(n*n+Q*Q);W+=(C-e)*this.zoomSpeed*.1*l,W=Math.min(Math.max(W,this.minZoom),this.maxZoom),C=e;const d=(F.touches[0].clientX+F.touches[1].clientX)/2,B=(F.touches[0].clientY+F.touches[1].clientY)/2,a=d-N,i=B-G,V=A.RotationFromQuaternion(U.rotation).buffer,Z=new t(V[0],V[3],V[6]),R=new t(V[1],V[4],V[7]);o=o.add(Z.multiply(-a*this.panSpeed*.025*l)),o=o.add(R.multiply(-i*this.panSpeed*.025*l)),N=d,G=B}else{const t=F.touches[0].clientX-N,U=F.touches[0].clientY-G;r-=t*this.orbitSpeed*.003,h+=U*this.orbitSpeed*.003,h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180),N=F.touches[0].clientX,G=F.touches[0].clientY}},D=(t,F,U)=>(1-U)*t+U*F;this.update=()=>{I=D(I,r,this.dampening),m=D(m,h,this.dampening),b=D(b,W,this.dampening),s=s.lerp(o,this.dampening);const l=s.x+b*Math.sin(I)*Math.cos(m),n=s.y-b*Math.sin(m),Q=s.z-b*Math.cos(I)*Math.cos(m);U.position=new t(l,n,Q);const e=s.subtract(U.position).normalize(),d=Math.asin(-e.y),B=Math.atan2(e.x,e.z);U.rotation=F.FromEuler(new t(d,B,0));const a=.025,i=.01,V=A.RotationFromQuaternion(U.rotation).buffer,Z=new t(-V[2],-V[5],-V[8]),R=new t(V[0],V[3],V[6]);X.KeyS&&(o=o.add(Z.multiply(a))),X.KeyW&&(o=o.subtract(Z.multiply(a))),X.KeyA&&(o=o.subtract(R.multiply(a))),X.KeyD&&(o=o.add(R.multiply(a))),X.KeyE&&(r+=i),X.KeyQ&&(r-=i),r=Math.min(Math.max(r,this.minAzimuth*Math.PI/180),this.maxAzimuth*Math.PI/180),X.KeyR&&(h+=i),X.KeyF&&(h-=i),h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180)};const f=t=>{t.preventDefault(),t.stopPropagation()};this.dispose=()=>{l.removeEventListener("dragenter",f),l.removeEventListener("dragover",f),l.removeEventListener("dragleave",f),l.removeEventListener("contextmenu",f),l.removeEventListener("mousedown",S),l.removeEventListener("mousemove",u),l.removeEventListener("wheel",Y),l.removeEventListener("touchstart",T),l.removeEventListener("touchend",x),l.removeEventListener("touchmove",H),d&&(window.removeEventListener("keydown",p),window.removeEventListener("keyup",y))},d&&(window.addEventListener("keydown",p),window.addEventListener("keyup",y)),l.addEventListener("dragenter",f),l.addEventListener("dragover",f),l.addEventListener("dragleave",f),l.addEventListener("contextmenu",f),l.addEventListener("mousedown",S),l.addEventListener("mousemove",u),l.addEventListener("wheel",Y),l.addEventListener("touchstart",T),l.addEventListener("touchend",x),l.addEventListener("touchmove",H),this.update()}}class Y{constructor(U,l){this.moveSpeed=1.5,this.lookSpeed=.7,this.dampening=.5;const n={};let Q=U.rotation.toEuler().x,e=U.rotation.toEuler().y,d=U.position,B=!1;const a=()=>{l.requestPointerLock()},i=()=>{B=document.pointerLockElement===l,B?l.addEventListener("mousemove",V):l.removeEventListener("mousemove",V)},V=t=>{const F=t.movementX,U=t.movementY;e+=F*this.lookSpeed*.001,Q-=U*this.lookSpeed*.001,Q=Math.max(-Math.PI/2,Math.min(Math.PI/2,Q))},Z=t=>{n[t.code]=!0,"ArrowUp"===t.code&&(n.KeyW=!0),"ArrowDown"===t.code&&(n.KeyS=!0),"ArrowLeft"===t.code&&(n.KeyA=!0),"ArrowRight"===t.code&&(n.KeyD=!0)},R=t=>{n[t.code]=!1,"ArrowUp"===t.code&&(n.KeyW=!1),"ArrowDown"===t.code&&(n.KeyS=!1),"ArrowLeft"===t.code&&(n.KeyA=!1),"ArrowRight"===t.code&&(n.KeyD=!1),"Escape"===t.code&&document.exitPointerLock()};this.update=()=>{const l=A.RotationFromQuaternion(U.rotation).buffer,B=new t(-l[2],-l[5],-l[8]),a=new t(l[0],l[3],l[6]);let i=new t(0,0,0);n.KeyS&&(i=i.add(B)),n.KeyW&&(i=i.subtract(B)),n.KeyA&&(i=i.subtract(a)),n.KeyD&&(i=i.add(a)),i=new t(i.x,0,i.z),i.magnitude()>0&&(i=i.normalize()),d=d.add(i.multiply(.01*this.moveSpeed)),U.position=U.position.add(d.subtract(U.position).multiply(this.dampening)),U.rotation=F.FromEuler(new t(Q,e,0))};const c=t=>{t.preventDefault(),t.stopPropagation()};this.dispose=()=>{l.removeEventListener("dragenter",c),l.removeEventListener("dragover",c),l.removeEventListener("dragleave",c),l.removeEventListener("contextmenu",c),l.removeEventListener("mousedown",a),document.removeEventListener("pointerlockchange",i),window.removeEventListener("keydown",Z),window.removeEventListener("keyup",R)},window.addEventListener("keydown",Z),window.addEventListener("keyup",R),l.addEventListener("dragenter",c),l.addEventListener("dragover",c),l.addEventListener("dragleave",c),l.addEventListener("contextmenu",c),l.addEventListener("mousedown",a),document.addEventListener("pointerlockchange",i),this.update()}}class T{constructor(t,F){this.normal=t,this.point=F}intersect(t,F){const U=this.normal.dot(F);if(Math.abs(U)<1e-4)return null;const l=this.normal.dot(this.point.subtract(t))/U;return l<0?null:t.add(F.multiply(l))}}class x{initialize(t){}render(){}dispose(){}}class H extends N{constructor(t,F=[]){super(t,F),this._renderData=null,this._depthIndex=new Uint32Array,this._splatTexture=null;const U=t.canvas,n=t.gl;let Q,e,d,A,B,a,i,V,Z,c,s;this._resize=()=>{this._camera&&(this._camera.data.setSize(U.width,U.height),this._camera.update(),e=n.getUniformLocation(this.program,"projection"),n.uniformMatrix4fv(e,!1,this._camera.data.projectionMatrix.buffer),d=n.getUniformLocation(this.program,"viewport"),n.uniform2fv(d,new Float32Array([U.width,U.height])))};const o=()=>{null!==t.renderProgram.worker?(Q=t.renderProgram.worker,Q.onmessage=t=>{if(t.data.depthIndex){const{depthIndex:F}=t.data;this._depthIndex=F,n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,F,n.STATIC_DRAW)}}):console.error("Render program is not initialized. Cannot render without worker")};this._initialize=()=>{if(!this._scene||!this._camera)return void console.error("Cannot render without scene and camera");this._resize(),this._scene.addEventListener("objectAdded",r),this._scene.addEventListener("objectRemoved",h);for(const t of this._scene.objects)t instanceof R&&(null===this._renderData?(this._renderData=t.data,t.addEventListener("objectChanged",W)):console.warn("Multiple Splatv objects are not currently supported"));if(null===this._renderData)return void console.error("Cannot render without Splatv object");A=n.getUniformLocation(this.program,"focal"),n.uniform2fv(A,new Float32Array([this._camera.data.fx,this._camera.data.fy])),B=n.getUniformLocation(this.program,"view"),n.uniformMatrix4fv(B,!1,this._camera.data.viewMatrix.buffer),this._splatTexture=n.createTexture(),a=n.getUniformLocation(this.program,"u_texture"),n.uniform1i(a,0),i=n.getUniformLocation(this.program,"time"),n.uniform1f(i,Math.sin(Date.now()/1e3)/2+.5),c=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,c),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-2,-2,2,-2,2,2,-2,2]),n.STATIC_DRAW),V=n.getAttribLocation(this.program,"position"),n.enableVertexAttribArray(V),n.vertexAttribPointer(V,2,n.FLOAT,!1,0,0),s=n.createBuffer(),Z=n.getAttribLocation(this.program,"index"),n.enableVertexAttribArray(Z),n.bindBuffer(n.ARRAY_BUFFER,s),o(),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,this._splatTexture),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST),n.texImage2D(n.TEXTURE_2D,0,n.RGBA32UI,this._renderData.width,this._renderData.height,0,n.RGBA_INTEGER,n.UNSIGNED_INT,this._renderData.data);const t=this._renderData.positions,F=new Float32Array((new l).buffer),U=new Uint32Array(this._renderData.vertexCount);U.fill(0),Q.postMessage({sortData:{positions:t,transforms:F,transformIndices:U,vertexCount:this._renderData.vertexCount}},[t.buffer,F.buffer,U.buffer])};const r=t=>{const F=t;F.object instanceof R&&(null===this._renderData?(this._renderData=F.object.data,F.object.addEventListener("objectChanged",W)):console.warn("Splatv not supported by default RenderProgram. Use VideoRenderProgram instead.")),this.dispose()},h=t=>{const F=t;F.object instanceof R&&this._renderData===F.object.data&&(this._renderData=null,F.object.removeEventListener("objectChanged",W)),this.dispose()},W=t=>{const F=t;F.object instanceof R&&this._renderData===F.object.data&&this.dispose()};this._render=()=>{this._scene&&this._camera?this._renderData?(this._camera.update(),Q.postMessage({viewProj:this._camera.data.viewProj.buffer}),n.viewport(0,0,U.width,U.height),n.clearColor(0,0,0,0),n.clear(n.COLOR_BUFFER_BIT),n.disable(n.DEPTH_TEST),n.enable(n.BLEND),n.blendFuncSeparate(n.ONE_MINUS_DST_ALPHA,n.ONE,n.ONE_MINUS_DST_ALPHA,n.ONE),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.uniformMatrix4fv(e,!1,this._camera.data.projectionMatrix.buffer),n.uniformMatrix4fv(B,!1,this._camera.data.viewMatrix.buffer),n.uniform1f(i,Math.sin(Date.now()/1e3)/2+.5),n.bindBuffer(n.ARRAY_BUFFER,c),n.vertexAttribPointer(V,2,n.FLOAT,!1,0,0),n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,this._depthIndex,n.STATIC_DRAW),n.vertexAttribIPointer(Z,1,n.INT,0,0),n.vertexAttribDivisor(Z,1),n.drawArraysInstanced(n.TRIANGLE_FAN,0,4,this._renderData.vertexCount)):console.warn("Cannot render without Splatv object"):console.error("Cannot render without scene and camera")},this._dispose=()=>{if(this._scene&&this._camera){this._scene.removeEventListener("objectAdded",r),this._scene.removeEventListener("objectRemoved",h);for(const t of this._scene.objects)t instanceof R&&this._renderData===t.data&&(this._renderData=null,t.removeEventListener("objectChanged",W));null==Q||Q.terminate(),n.deleteTexture(this._splatTexture),n.deleteBuffer(s),n.deleteBuffer(c)}else console.error("Cannot dispose without scene and camera")}}get renderData(){return this._renderData}_getVertexSource(){return"#version 300 es\nprecision highp float;\nprecision highp int;\n \nuniform highp usampler2D u_texture;\nuniform mat4 projection, view;\nuniform vec2 focal;\nuniform vec2 viewport;\nuniform float time;\n \nin vec2 position;\nin int index;\n \nout vec4 vColor;\nout vec2 vPosition;\n \nvoid main () {\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n uvec4 motion1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 3u, uint(index) >> 10), 0);\n vec2 trbf = unpackHalf2x16(motion1.w);\n float dt = time - trbf.x;\n\n float topacity = exp(-1.0 * pow(dt / trbf.y, 2.0));\n if(topacity < 0.02) return;\n\n uvec4 motion0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 2u, uint(index) >> 10), 0);\n uvec4 static0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2), uint(index) >> 10), 0);\n\n vec2 m0 = unpackHalf2x16(motion0.x), m1 = unpackHalf2x16(motion0.y), m2 = unpackHalf2x16(motion0.z), \n m3 = unpackHalf2x16(motion0.w), m4 = unpackHalf2x16(motion1.x); \n \n vec4 trot = vec4(unpackHalf2x16(motion1.y).xy, unpackHalf2x16(motion1.z).xy) * dt;\n vec3 tpos = (vec3(m0.xy, m1.x) * dt + vec3(m1.y, m2.xy) * dt*dt + vec3(m3.xy, m4.x) * dt*dt*dt);\n \n vec4 cam = view * vec4(uintBitsToFloat(static0.xyz) + tpos, 1);\n vec4 pos = projection * cam;\n \n float clip = 1.2 * pos.w;\n if (pos.z < -clip || pos.x < -clip || pos.x > clip || pos.y < -clip || pos.y > clip) return;\n uvec4 static1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 1u, uint(index) >> 10), 0);\n\n vec4 rot = vec4(unpackHalf2x16(static0.w).xy, unpackHalf2x16(static1.x).xy) + trot;\n vec3 scale = vec3(unpackHalf2x16(static1.y).xy, unpackHalf2x16(static1.z).x);\n rot /= sqrt(dot(rot, rot));\n \n mat3 S = mat3(scale.x, 0.0, 0.0, 0.0, scale.y, 0.0, 0.0, 0.0, scale.z);\n mat3 R = mat3(\n 1.0 - 2.0 * (rot.z * rot.z + rot.w * rot.w), 2.0 * (rot.y * rot.z - rot.x * rot.w), 2.0 * (rot.y * rot.w + rot.x * rot.z),\n 2.0 * (rot.y * rot.z + rot.x * rot.w), 1.0 - 2.0 * (rot.y * rot.y + rot.w * rot.w), 2.0 * (rot.z * rot.w - rot.x * rot.y),\n 2.0 * (rot.y * rot.w - rot.x * rot.z), 2.0 * (rot.z * rot.w + rot.x * rot.y), 1.0 - 2.0 * (rot.y * rot.y + rot.z * rot.z));\n mat3 M = S * R;\n mat3 Vrk = 4.0 * transpose(M) * M;\n mat3 J = mat3(\n focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z), \n 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z), \n 0., 0., 0.\n );\n \n mat3 T = transpose(mat3(view)) * J;\n mat3 cov2d = transpose(T) * Vrk * T;\n \n float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;\n float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));\n float lambda1 = mid + radius, lambda2 = mid - radius;\n \n if(lambda2 < 0.0) return;\n vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));\n vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;\n vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);\n \n uint rgba = static1.w;\n vColor = \n clamp(pos.z/pos.w+1.0, 0.0, 1.0) * \n vec4(1.0, 1.0, 1.0, topacity) *\n vec4(\n (rgba) & 0xffu, \n (rgba >> 8) & 0xffu, \n (rgba >> 16) & 0xffu, \n (rgba >> 24) & 0xffu) / 255.0;\n\n vec2 vCenter = vec2(pos) / pos.w;\n gl_Position = vec4(\n vCenter \n + position.x * majorAxis / viewport \n + position.y * minorAxis / viewport, 0.0, 1.0);\n\n vPosition = position;\n}\n"}_getFragmentSource(){return"#version 300 es\nprecision highp float;\n \nin vec4 vColor;\nin vec2 vPosition;\n\nout vec4 fragColor;\n\nvoid main () {\n float A = -dot(vPosition, vPosition);\n if (A < -4.0) discard;\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n}\n"}}class D{constructor(t,F,U){this.bounds=t,this.boxes=F,this.left=null,this.right=null,this.pointIndices=[],U.length>1?this.split(t,F,U):U.length>0&&(this.pointIndices=U)}split(t,F,U){const l=t.size().maxComponent();U.sort(((t,U)=>F[t].center().getComponent(l)-F[U].center().getComponent(l)));const n=Math.floor(U.length/2),Q=U.slice(0,n),e=U.slice(n);this.left=new D(t,F,Q),this.right=new D(t,F,e)}queryRange(t){return this.bounds.intersects(t)?null!==this.left&&null!==this.right?this.left.queryRange(t).concat(this.right.queryRange(t)):this.pointIndices.filter((F=>t.intersects(this.boxes[F]))):[]}}class f{constructor(t,F){const U=F.map(((t,F)=>F));this.root=new D(t,F,U)}queryRange(t){return this.root.queryRange(t)}}class w{constructor(F,U=100,l=1){let n=0,Q=null,e=[];this.testPoint=(d,A)=>{if(null===F.renderData||null===F.camera)return console.error("IntersectionTester cannot be called before renderProgram has been initialized"),null;if((()=>{if(null===F.renderData)return void console.error("IntersectionTester cannot be called before renderProgram has been initialized");e=[];const U=F.renderData,l=new Array(U.offsets.size);let d=0;const A=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0));for(const t of U.offsets.keys()){const F=t.bounds;l[d++]=F,A.expand(F.min),A.expand(F.max),e.push(t)}A.permute(),Q=new f(A,l),n=U.vertexCount})(),null===Q)return console.error("Failed to build octree for IntersectionTester"),null;const B=F.renderData,a=F.camera;n!==B.vertexCount&&console.warn("IntersectionTester has not been rebuilt since the last render");const i=a.screenPointToRay(d,A);for(let F=0;F<U;F+=l){const U=a.position.add(i.multiply(F)),n=new t(U.x-l/2,U.y-l/2,U.z-l/2),d=new t(U.x+l/2,U.y+l/2,U.z+l/2),A=new V(n,d),B=Q.queryRange(A);if(B.length>0)return e[B[0]]}return null}}}export{o as Camera,c as CameraData,p as Color32,Y as FPSControls,S as FadeInPass,w as IntersectionTester,I as Loader,A as Matrix3,l as Matrix4,d as Object3D,u as OrbitControls,m as PLYLoader,T as Plane,F as Quaternion,E as RenderData,y as RenderProgram,r as Scene,x as ShaderPass,N as ShaderProgram,Z as Splat,B as SplatData,R as Splatv,a as SplatvData,b as SplatvLoader,t as Vector3,s as Vector4,H as VideoRenderProgram,k as WebGLRenderer}; | |
//# sourceMappingURL=index.js.map | |