mirror of
https://github.com/WhitestormJS/whs.js.git
synced 2026-01-18 16:03:24 +00:00
42998 lines
3.6 MiB
42998 lines
3.6 MiB
/* Built for whs v2.2.0-beta.0 */
|
|
// Polyfills
|
|
|
|
if ( Number.EPSILON === undefined ) {
|
|
|
|
Number.EPSILON = Math.pow( 2, - 52 );
|
|
|
|
}
|
|
|
|
if ( Number.isInteger === undefined ) {
|
|
|
|
// Missing in IE
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
|
|
|
|
Number.isInteger = function ( value ) {
|
|
|
|
return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
//
|
|
|
|
if ( Math.sign === undefined ) {
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
|
|
|
|
Math.sign = function ( x ) {
|
|
|
|
return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if ( Function.prototype.name === undefined ) {
|
|
|
|
// Missing in IE
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
|
|
|
|
Object.defineProperty( Function.prototype, 'name', {
|
|
|
|
get: function () {
|
|
|
|
return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
if ( Object.assign === undefined ) {
|
|
|
|
// Missing in IE
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
|
|
( function () {
|
|
|
|
Object.assign = function ( target ) {
|
|
|
|
if ( target === undefined || target === null ) {
|
|
|
|
throw new TypeError( 'Cannot convert undefined or null to object' );
|
|
|
|
}
|
|
|
|
var output = Object( target );
|
|
|
|
for ( var index = 1; index < arguments.length; index ++ ) {
|
|
|
|
var source = arguments[ index ];
|
|
|
|
if ( source !== undefined && source !== null ) {
|
|
|
|
for ( var nextKey in source ) {
|
|
|
|
if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
|
|
|
|
output[ nextKey ] = source[ nextKey ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
};
|
|
|
|
} )();
|
|
|
|
}
|
|
|
|
/**
|
|
* https://github.com/mrdoob/eventdispatcher.js/
|
|
*/
|
|
|
|
function EventDispatcher() {}
|
|
|
|
Object.assign( EventDispatcher.prototype, {
|
|
|
|
addEventListener: function ( type, listener ) {
|
|
|
|
if ( this._listeners === undefined ) this._listeners = {};
|
|
|
|
var listeners = this._listeners;
|
|
|
|
if ( listeners[ type ] === undefined ) {
|
|
|
|
listeners[ type ] = [];
|
|
|
|
}
|
|
|
|
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
|
|
|
|
listeners[ type ].push( listener );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
hasEventListener: function ( type, listener ) {
|
|
|
|
if ( this._listeners === undefined ) return false;
|
|
|
|
var listeners = this._listeners;
|
|
|
|
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
|
|
|
|
},
|
|
|
|
removeEventListener: function ( type, listener ) {
|
|
|
|
if ( this._listeners === undefined ) return;
|
|
|
|
var listeners = this._listeners;
|
|
var listenerArray = listeners[ type ];
|
|
|
|
if ( listenerArray !== undefined ) {
|
|
|
|
var index = listenerArray.indexOf( listener );
|
|
|
|
if ( index !== - 1 ) {
|
|
|
|
listenerArray.splice( index, 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
dispatchEvent: function ( event ) {
|
|
|
|
if ( this._listeners === undefined ) return;
|
|
|
|
var listeners = this._listeners;
|
|
var listenerArray = listeners[ event.type ];
|
|
|
|
if ( listenerArray !== undefined ) {
|
|
|
|
event.target = this;
|
|
|
|
var array = [], i = 0;
|
|
var length = listenerArray.length;
|
|
|
|
for ( i = 0; i < length; i ++ ) {
|
|
|
|
array[ i ] = listenerArray[ i ];
|
|
|
|
}
|
|
|
|
for ( i = 0; i < length; i ++ ) {
|
|
|
|
array[ i ].call( this, event );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
var REVISION = '85';
|
|
var CullFaceNone = 0;
|
|
var CullFaceBack = 1;
|
|
var CullFaceFront = 2;
|
|
var FrontFaceDirectionCW = 0;
|
|
var PCFShadowMap = 1;
|
|
var PCFSoftShadowMap = 2;
|
|
var FrontSide = 0;
|
|
var BackSide = 1;
|
|
var DoubleSide = 2;
|
|
var FlatShading = 1;
|
|
var SmoothShading = 2;
|
|
var NoColors = 0;
|
|
var FaceColors = 1;
|
|
var VertexColors = 2;
|
|
var NoBlending = 0;
|
|
var NormalBlending = 1;
|
|
var AdditiveBlending = 2;
|
|
var SubtractiveBlending = 3;
|
|
var MultiplyBlending = 4;
|
|
var CustomBlending = 5;
|
|
var AddEquation = 100;
|
|
var SubtractEquation = 101;
|
|
var ReverseSubtractEquation = 102;
|
|
var MinEquation = 103;
|
|
var MaxEquation = 104;
|
|
var ZeroFactor = 200;
|
|
var OneFactor = 201;
|
|
var SrcColorFactor = 202;
|
|
var OneMinusSrcColorFactor = 203;
|
|
var SrcAlphaFactor = 204;
|
|
var OneMinusSrcAlphaFactor = 205;
|
|
var DstAlphaFactor = 206;
|
|
var OneMinusDstAlphaFactor = 207;
|
|
var DstColorFactor = 208;
|
|
var OneMinusDstColorFactor = 209;
|
|
var SrcAlphaSaturateFactor = 210;
|
|
var NeverDepth = 0;
|
|
var AlwaysDepth = 1;
|
|
var LessDepth = 2;
|
|
var LessEqualDepth = 3;
|
|
var EqualDepth = 4;
|
|
var GreaterEqualDepth = 5;
|
|
var GreaterDepth = 6;
|
|
var NotEqualDepth = 7;
|
|
var MultiplyOperation = 0;
|
|
var MixOperation = 1;
|
|
var AddOperation = 2;
|
|
var NoToneMapping = 0;
|
|
var LinearToneMapping = 1;
|
|
var ReinhardToneMapping = 2;
|
|
var Uncharted2ToneMapping = 3;
|
|
var CineonToneMapping = 4;
|
|
var UVMapping = 300;
|
|
var CubeReflectionMapping = 301;
|
|
var CubeRefractionMapping = 302;
|
|
var EquirectangularReflectionMapping = 303;
|
|
var EquirectangularRefractionMapping = 304;
|
|
var SphericalReflectionMapping = 305;
|
|
var CubeUVReflectionMapping = 306;
|
|
var CubeUVRefractionMapping = 307;
|
|
var RepeatWrapping = 1000;
|
|
var ClampToEdgeWrapping = 1001;
|
|
var MirroredRepeatWrapping = 1002;
|
|
var NearestFilter = 1003;
|
|
var NearestMipMapNearestFilter = 1004;
|
|
var NearestMipMapLinearFilter = 1005;
|
|
var LinearFilter = 1006;
|
|
var LinearMipMapNearestFilter = 1007;
|
|
var LinearMipMapLinearFilter = 1008;
|
|
var UnsignedByteType = 1009;
|
|
var ByteType = 1010;
|
|
var ShortType = 1011;
|
|
var UnsignedShortType = 1012;
|
|
var IntType = 1013;
|
|
var UnsignedIntType = 1014;
|
|
var FloatType = 1015;
|
|
var HalfFloatType = 1016;
|
|
var UnsignedShort4444Type = 1017;
|
|
var UnsignedShort5551Type = 1018;
|
|
var UnsignedShort565Type = 1019;
|
|
var UnsignedInt248Type = 1020;
|
|
var AlphaFormat = 1021;
|
|
var RGBFormat = 1022;
|
|
var RGBAFormat = 1023;
|
|
var LuminanceFormat = 1024;
|
|
var LuminanceAlphaFormat = 1025;
|
|
var DepthFormat = 1026;
|
|
var DepthStencilFormat = 1027;
|
|
var RGB_S3TC_DXT1_Format = 2001;
|
|
var RGBA_S3TC_DXT1_Format = 2002;
|
|
var RGBA_S3TC_DXT3_Format = 2003;
|
|
var RGBA_S3TC_DXT5_Format = 2004;
|
|
var RGB_PVRTC_4BPPV1_Format = 2100;
|
|
var RGB_PVRTC_2BPPV1_Format = 2101;
|
|
var RGBA_PVRTC_4BPPV1_Format = 2102;
|
|
var RGBA_PVRTC_2BPPV1_Format = 2103;
|
|
var RGB_ETC1_Format = 2151;
|
|
var LoopOnce = 2200;
|
|
var LoopRepeat = 2201;
|
|
var LoopPingPong = 2202;
|
|
var InterpolateDiscrete = 2300;
|
|
var InterpolateLinear = 2301;
|
|
var InterpolateSmooth = 2302;
|
|
var ZeroCurvatureEnding = 2400;
|
|
var ZeroSlopeEnding = 2401;
|
|
var WrapAroundEnding = 2402;
|
|
var TrianglesDrawMode = 0;
|
|
var TriangleStripDrawMode = 1;
|
|
var TriangleFanDrawMode = 2;
|
|
var LinearEncoding = 3000;
|
|
var sRGBEncoding = 3001;
|
|
var GammaEncoding = 3007;
|
|
var RGBEEncoding = 3002;
|
|
var RGBM7Encoding = 3004;
|
|
var RGBM16Encoding = 3005;
|
|
var RGBDEncoding = 3006;
|
|
var BasicDepthPacking = 3200;
|
|
var RGBADepthPacking = 3201;
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
var _Math = {
|
|
|
|
DEG2RAD: Math.PI / 180,
|
|
RAD2DEG: 180 / Math.PI,
|
|
|
|
generateUUID: function () {
|
|
|
|
// http://www.broofa.com/Tools/Math.uuid.htm
|
|
|
|
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );
|
|
var uuid = new Array( 36 );
|
|
var rnd = 0, r;
|
|
|
|
return function generateUUID() {
|
|
|
|
for ( var i = 0; i < 36; i ++ ) {
|
|
|
|
if ( i === 8 || i === 13 || i === 18 || i === 23 ) {
|
|
|
|
uuid[ i ] = '-';
|
|
|
|
} else if ( i === 14 ) {
|
|
|
|
uuid[ i ] = '4';
|
|
|
|
} else {
|
|
|
|
if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;
|
|
r = rnd & 0xf;
|
|
rnd = rnd >> 4;
|
|
uuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return uuid.join( '' );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clamp: function ( value, min, max ) {
|
|
|
|
return Math.max( min, Math.min( max, value ) );
|
|
|
|
},
|
|
|
|
// compute euclidian modulo of m % n
|
|
// https://en.wikipedia.org/wiki/Modulo_operation
|
|
|
|
euclideanModulo: function ( n, m ) {
|
|
|
|
return ( ( n % m ) + m ) % m;
|
|
|
|
},
|
|
|
|
// Linear mapping from range <a1, a2> to range <b1, b2>
|
|
|
|
mapLinear: function ( x, a1, a2, b1, b2 ) {
|
|
|
|
return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
|
|
|
|
},
|
|
|
|
// https://en.wikipedia.org/wiki/Linear_interpolation
|
|
|
|
lerp: function ( x, y, t ) {
|
|
|
|
return ( 1 - t ) * x + t * y;
|
|
|
|
},
|
|
|
|
// http://en.wikipedia.org/wiki/Smoothstep
|
|
|
|
smoothstep: function ( x, min, max ) {
|
|
|
|
if ( x <= min ) return 0;
|
|
if ( x >= max ) return 1;
|
|
|
|
x = ( x - min ) / ( max - min );
|
|
|
|
return x * x * ( 3 - 2 * x );
|
|
|
|
},
|
|
|
|
smootherstep: function ( x, min, max ) {
|
|
|
|
if ( x <= min ) return 0;
|
|
if ( x >= max ) return 1;
|
|
|
|
x = ( x - min ) / ( max - min );
|
|
|
|
return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
|
|
|
|
},
|
|
|
|
// Random integer from <low, high> interval
|
|
|
|
randInt: function ( low, high ) {
|
|
|
|
return low + Math.floor( Math.random() * ( high - low + 1 ) );
|
|
|
|
},
|
|
|
|
// Random float from <low, high> interval
|
|
|
|
randFloat: function ( low, high ) {
|
|
|
|
return low + Math.random() * ( high - low );
|
|
|
|
},
|
|
|
|
// Random float from <-range/2, range/2> interval
|
|
|
|
randFloatSpread: function ( range ) {
|
|
|
|
return range * ( 0.5 - Math.random() );
|
|
|
|
},
|
|
|
|
degToRad: function ( degrees ) {
|
|
|
|
return degrees * _Math.DEG2RAD;
|
|
|
|
},
|
|
|
|
radToDeg: function ( radians ) {
|
|
|
|
return radians * _Math.RAD2DEG;
|
|
|
|
},
|
|
|
|
isPowerOfTwo: function ( value ) {
|
|
|
|
return ( value & ( value - 1 ) ) === 0 && value !== 0;
|
|
|
|
},
|
|
|
|
nearestPowerOfTwo: function ( value ) {
|
|
|
|
return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
|
|
|
|
},
|
|
|
|
nextPowerOfTwo: function ( value ) {
|
|
|
|
value --;
|
|
value |= value >> 1;
|
|
value |= value >> 2;
|
|
value |= value >> 4;
|
|
value |= value >> 8;
|
|
value |= value >> 16;
|
|
value ++;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author philogb / http://blog.thejit.org/
|
|
* @author egraether / http://egraether.com/
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
*/
|
|
|
|
function Vector2( x, y ) {
|
|
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
|
|
}
|
|
|
|
Object.defineProperties( Vector2.prototype, {
|
|
|
|
"width" : {
|
|
|
|
get: function () {
|
|
|
|
return this.x;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this.x = value;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"height" : {
|
|
|
|
get: function () {
|
|
|
|
return this.y;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this.y = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Vector2.prototype, {
|
|
|
|
isVector2: true,
|
|
|
|
set: function ( x, y ) {
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setScalar: function ( scalar ) {
|
|
|
|
this.x = scalar;
|
|
this.y = scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setX: function ( x ) {
|
|
|
|
this.x = x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setY: function ( y ) {
|
|
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setComponent: function ( index, value ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: this.x = value; break;
|
|
case 1: this.y = value; break;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getComponent: function ( index ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: return this.x;
|
|
case 1: return this.y;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.x, this.y );
|
|
|
|
},
|
|
|
|
copy: function ( v ) {
|
|
|
|
this.x = v.x;
|
|
this.y = v.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
add: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
|
|
return this.addVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScalar: function ( s ) {
|
|
|
|
this.x += s;
|
|
this.y += s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addVectors: function ( a, b ) {
|
|
|
|
this.x = a.x + b.x;
|
|
this.y = a.y + b.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScaledVector: function ( v, s ) {
|
|
|
|
this.x += v.x * s;
|
|
this.y += v.y * s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
sub: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
|
|
return this.subVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subScalar: function ( s ) {
|
|
|
|
this.x -= s;
|
|
this.y -= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subVectors: function ( a, b ) {
|
|
|
|
this.x = a.x - b.x;
|
|
this.y = a.y - b.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiply: function ( v ) {
|
|
|
|
this.x *= v.x;
|
|
this.y *= v.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( scalar ) {
|
|
|
|
this.x *= scalar;
|
|
this.y *= scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
divide: function ( v ) {
|
|
|
|
this.x /= v.x;
|
|
this.y /= v.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
divideScalar: function ( scalar ) {
|
|
|
|
return this.multiplyScalar( 1 / scalar );
|
|
|
|
},
|
|
|
|
min: function ( v ) {
|
|
|
|
this.x = Math.min( this.x, v.x );
|
|
this.y = Math.min( this.y, v.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
max: function ( v ) {
|
|
|
|
this.x = Math.max( this.x, v.x );
|
|
this.y = Math.max( this.y, v.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clamp: function ( min, max ) {
|
|
|
|
// This function assumes min < max, if this assumption isn't true it will not operate correctly
|
|
|
|
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
|
|
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clampScalar: function () {
|
|
|
|
var min = new Vector2();
|
|
var max = new Vector2();
|
|
|
|
return function clampScalar( minVal, maxVal ) {
|
|
|
|
min.set( minVal, minVal );
|
|
max.set( maxVal, maxVal );
|
|
|
|
return this.clamp( min, max );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clampLength: function ( min, max ) {
|
|
|
|
var length = this.length();
|
|
|
|
return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
|
|
|
|
},
|
|
|
|
floor: function () {
|
|
|
|
this.x = Math.floor( this.x );
|
|
this.y = Math.floor( this.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
ceil: function () {
|
|
|
|
this.x = Math.ceil( this.x );
|
|
this.y = Math.ceil( this.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
round: function () {
|
|
|
|
this.x = Math.round( this.x );
|
|
this.y = Math.round( this.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
roundToZero: function () {
|
|
|
|
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
|
|
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
negate: function () {
|
|
|
|
this.x = - this.x;
|
|
this.y = - this.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dot: function ( v ) {
|
|
|
|
return this.x * v.x + this.y * v.y;
|
|
|
|
},
|
|
|
|
lengthSq: function () {
|
|
|
|
return this.x * this.x + this.y * this.y;
|
|
|
|
},
|
|
|
|
length: function () {
|
|
|
|
return Math.sqrt( this.x * this.x + this.y * this.y );
|
|
|
|
},
|
|
|
|
lengthManhattan: function() {
|
|
|
|
return Math.abs( this.x ) + Math.abs( this.y );
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
return this.divideScalar( this.length() );
|
|
|
|
},
|
|
|
|
angle: function () {
|
|
|
|
// computes the angle in radians with respect to the positive x-axis
|
|
|
|
var angle = Math.atan2( this.y, this.x );
|
|
|
|
if ( angle < 0 ) angle += 2 * Math.PI;
|
|
|
|
return angle;
|
|
|
|
},
|
|
|
|
distanceTo: function ( v ) {
|
|
|
|
return Math.sqrt( this.distanceToSquared( v ) );
|
|
|
|
},
|
|
|
|
distanceToSquared: function ( v ) {
|
|
|
|
var dx = this.x - v.x, dy = this.y - v.y;
|
|
return dx * dx + dy * dy;
|
|
|
|
},
|
|
|
|
distanceToManhattan: function ( v ) {
|
|
|
|
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
|
|
|
|
},
|
|
|
|
setLength: function ( length ) {
|
|
|
|
return this.multiplyScalar( length / this.length() );
|
|
|
|
},
|
|
|
|
lerp: function ( v, alpha ) {
|
|
|
|
this.x += ( v.x - this.x ) * alpha;
|
|
this.y += ( v.y - this.y ) * alpha;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
lerpVectors: function ( v1, v2, alpha ) {
|
|
|
|
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
|
|
|
|
},
|
|
|
|
equals: function ( v ) {
|
|
|
|
return ( ( v.x === this.x ) && ( v.y === this.y ) );
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.x = array[ offset ];
|
|
this.y = array[ offset + 1 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this.x;
|
|
array[ offset + 1 ] = this.y;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
fromBufferAttribute: function ( attribute, index, offset ) {
|
|
|
|
if ( offset !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
|
|
|
|
}
|
|
|
|
this.x = attribute.getX( index );
|
|
this.y = attribute.getY( index );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
rotateAround: function ( center, angle ) {
|
|
|
|
var c = Math.cos( angle ), s = Math.sin( angle );
|
|
|
|
var x = this.x - center.x;
|
|
var y = this.y - center.y;
|
|
|
|
this.x = x * c - y * s + center.x;
|
|
this.y = x * s + y * c + center.y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author szimek / https://github.com/szimek/
|
|
*/
|
|
|
|
var textureId = 0;
|
|
|
|
function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
|
|
|
|
Object.defineProperty( this, 'id', { value: textureId ++ } );
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.name = '';
|
|
|
|
this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
|
|
this.mipmaps = [];
|
|
|
|
this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
|
|
|
|
this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
|
|
this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
|
|
|
|
this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
|
|
this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;
|
|
|
|
this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
|
|
|
|
this.format = format !== undefined ? format : RGBAFormat;
|
|
this.type = type !== undefined ? type : UnsignedByteType;
|
|
|
|
this.offset = new Vector2( 0, 0 );
|
|
this.repeat = new Vector2( 1, 1 );
|
|
|
|
this.generateMipmaps = true;
|
|
this.premultiplyAlpha = false;
|
|
this.flipY = true;
|
|
this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
|
|
|
|
// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
|
|
//
|
|
// Also changing the encoding after already used by a Material will not automatically make the Material
|
|
// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
|
|
this.encoding = encoding !== undefined ? encoding : LinearEncoding;
|
|
|
|
this.version = 0;
|
|
this.onUpdate = null;
|
|
|
|
}
|
|
|
|
Texture.DEFAULT_IMAGE = undefined;
|
|
Texture.DEFAULT_MAPPING = UVMapping;
|
|
|
|
Object.defineProperty( Texture.prototype, "needsUpdate", {
|
|
|
|
set: function ( value ) {
|
|
|
|
if ( value === true ) this.version ++;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Texture.prototype, EventDispatcher.prototype, {
|
|
|
|
constructor: Texture,
|
|
|
|
isTexture: true,
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.name = source.name;
|
|
|
|
this.image = source.image;
|
|
this.mipmaps = source.mipmaps.slice( 0 );
|
|
|
|
this.mapping = source.mapping;
|
|
|
|
this.wrapS = source.wrapS;
|
|
this.wrapT = source.wrapT;
|
|
|
|
this.magFilter = source.magFilter;
|
|
this.minFilter = source.minFilter;
|
|
|
|
this.anisotropy = source.anisotropy;
|
|
|
|
this.format = source.format;
|
|
this.type = source.type;
|
|
|
|
this.offset.copy( source.offset );
|
|
this.repeat.copy( source.repeat );
|
|
|
|
this.generateMipmaps = source.generateMipmaps;
|
|
this.premultiplyAlpha = source.premultiplyAlpha;
|
|
this.flipY = source.flipY;
|
|
this.unpackAlignment = source.unpackAlignment;
|
|
this.encoding = source.encoding;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
if ( meta.textures[ this.uuid ] !== undefined ) {
|
|
|
|
return meta.textures[ this.uuid ];
|
|
|
|
}
|
|
|
|
function getDataURL( image ) {
|
|
|
|
var canvas;
|
|
|
|
if ( image.toDataURL !== undefined ) {
|
|
|
|
canvas = image;
|
|
|
|
} else {
|
|
|
|
canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
|
|
canvas.width = image.width;
|
|
canvas.height = image.height;
|
|
|
|
canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );
|
|
|
|
}
|
|
|
|
if ( canvas.width > 2048 || canvas.height > 2048 ) {
|
|
|
|
return canvas.toDataURL( 'image/jpeg', 0.6 );
|
|
|
|
} else {
|
|
|
|
return canvas.toDataURL( 'image/png' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var output = {
|
|
metadata: {
|
|
version: 4.5,
|
|
type: 'Texture',
|
|
generator: 'Texture.toJSON'
|
|
},
|
|
|
|
uuid: this.uuid,
|
|
name: this.name,
|
|
|
|
mapping: this.mapping,
|
|
|
|
repeat: [ this.repeat.x, this.repeat.y ],
|
|
offset: [ this.offset.x, this.offset.y ],
|
|
wrap: [ this.wrapS, this.wrapT ],
|
|
|
|
minFilter: this.minFilter,
|
|
magFilter: this.magFilter,
|
|
anisotropy: this.anisotropy,
|
|
|
|
flipY: this.flipY
|
|
};
|
|
|
|
if ( this.image !== undefined ) {
|
|
|
|
// TODO: Move to THREE.Image
|
|
|
|
var image = this.image;
|
|
|
|
if ( image.uuid === undefined ) {
|
|
|
|
image.uuid = _Math.generateUUID(); // UGH
|
|
|
|
}
|
|
|
|
if ( meta.images[ image.uuid ] === undefined ) {
|
|
|
|
meta.images[ image.uuid ] = {
|
|
uuid: image.uuid,
|
|
url: getDataURL( image )
|
|
};
|
|
|
|
}
|
|
|
|
output.image = image.uuid;
|
|
|
|
}
|
|
|
|
meta.textures[ this.uuid ] = output;
|
|
|
|
return output;
|
|
|
|
},
|
|
|
|
dispose: function () {
|
|
|
|
this.dispatchEvent( { type: 'dispose' } );
|
|
|
|
},
|
|
|
|
transformUv: function ( uv ) {
|
|
|
|
if ( this.mapping !== UVMapping ) return;
|
|
|
|
uv.multiply( this.repeat );
|
|
uv.add( this.offset );
|
|
|
|
if ( uv.x < 0 || uv.x > 1 ) {
|
|
|
|
switch ( this.wrapS ) {
|
|
|
|
case RepeatWrapping:
|
|
|
|
uv.x = uv.x - Math.floor( uv.x );
|
|
break;
|
|
|
|
case ClampToEdgeWrapping:
|
|
|
|
uv.x = uv.x < 0 ? 0 : 1;
|
|
break;
|
|
|
|
case MirroredRepeatWrapping:
|
|
|
|
if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
|
|
|
|
uv.x = Math.ceil( uv.x ) - uv.x;
|
|
|
|
} else {
|
|
|
|
uv.x = uv.x - Math.floor( uv.x );
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( uv.y < 0 || uv.y > 1 ) {
|
|
|
|
switch ( this.wrapT ) {
|
|
|
|
case RepeatWrapping:
|
|
|
|
uv.y = uv.y - Math.floor( uv.y );
|
|
break;
|
|
|
|
case ClampToEdgeWrapping:
|
|
|
|
uv.y = uv.y < 0 ? 0 : 1;
|
|
break;
|
|
|
|
case MirroredRepeatWrapping:
|
|
|
|
if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
|
|
|
|
uv.y = Math.ceil( uv.y ) - uv.y;
|
|
|
|
} else {
|
|
|
|
uv.y = uv.y - Math.floor( uv.y );
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.flipY ) {
|
|
|
|
uv.y = 1 - uv.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author supereggbert / http://www.paulbrunt.co.uk/
|
|
* @author philogb / http://blog.thejit.org/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author egraether / http://egraether.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function Vector4( x, y, z, w ) {
|
|
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
this.w = ( w !== undefined ) ? w : 1;
|
|
|
|
}
|
|
|
|
Object.assign( Vector4.prototype, {
|
|
|
|
isVector4: true,
|
|
|
|
set: function ( x, y, z, w ) {
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.w = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setScalar: function ( scalar ) {
|
|
|
|
this.x = scalar;
|
|
this.y = scalar;
|
|
this.z = scalar;
|
|
this.w = scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setX: function ( x ) {
|
|
|
|
this.x = x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setY: function ( y ) {
|
|
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setZ: function ( z ) {
|
|
|
|
this.z = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setW: function ( w ) {
|
|
|
|
this.w = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setComponent: function ( index, value ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: this.x = value; break;
|
|
case 1: this.y = value; break;
|
|
case 2: this.z = value; break;
|
|
case 3: this.w = value; break;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getComponent: function ( index ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: return this.x;
|
|
case 1: return this.y;
|
|
case 2: return this.z;
|
|
case 3: return this.w;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.x, this.y, this.z, this.w );
|
|
|
|
},
|
|
|
|
copy: function ( v ) {
|
|
|
|
this.x = v.x;
|
|
this.y = v.y;
|
|
this.z = v.z;
|
|
this.w = ( v.w !== undefined ) ? v.w : 1;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
add: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
|
|
return this.addVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z;
|
|
this.w += v.w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScalar: function ( s ) {
|
|
|
|
this.x += s;
|
|
this.y += s;
|
|
this.z += s;
|
|
this.w += s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addVectors: function ( a, b ) {
|
|
|
|
this.x = a.x + b.x;
|
|
this.y = a.y + b.y;
|
|
this.z = a.z + b.z;
|
|
this.w = a.w + b.w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScaledVector: function ( v, s ) {
|
|
|
|
this.x += v.x * s;
|
|
this.y += v.y * s;
|
|
this.z += v.z * s;
|
|
this.w += v.w * s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
sub: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
|
|
return this.subVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
this.z -= v.z;
|
|
this.w -= v.w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subScalar: function ( s ) {
|
|
|
|
this.x -= s;
|
|
this.y -= s;
|
|
this.z -= s;
|
|
this.w -= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subVectors: function ( a, b ) {
|
|
|
|
this.x = a.x - b.x;
|
|
this.y = a.y - b.y;
|
|
this.z = a.z - b.z;
|
|
this.w = a.w - b.w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( scalar ) {
|
|
|
|
this.x *= scalar;
|
|
this.y *= scalar;
|
|
this.z *= scalar;
|
|
this.w *= scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyMatrix4: function ( m ) {
|
|
|
|
var x = this.x, y = this.y, z = this.z, w = this.w;
|
|
var e = m.elements;
|
|
|
|
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
|
|
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
|
|
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
|
|
this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
divideScalar: function ( scalar ) {
|
|
|
|
return this.multiplyScalar( 1 / scalar );
|
|
|
|
},
|
|
|
|
setAxisAngleFromQuaternion: function ( q ) {
|
|
|
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
|
|
|
|
// q is assumed to be normalized
|
|
|
|
this.w = 2 * Math.acos( q.w );
|
|
|
|
var s = Math.sqrt( 1 - q.w * q.w );
|
|
|
|
if ( s < 0.0001 ) {
|
|
|
|
this.x = 1;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
|
|
} else {
|
|
|
|
this.x = q.x / s;
|
|
this.y = q.y / s;
|
|
this.z = q.z / s;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setAxisAngleFromRotationMatrix: function ( m ) {
|
|
|
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
|
|
|
|
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
|
|
var angle, x, y, z, // variables for result
|
|
epsilon = 0.01, // margin to allow for rounding errors
|
|
epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
|
|
|
|
te = m.elements,
|
|
|
|
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
|
|
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
|
|
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
|
|
|
|
if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
|
|
( Math.abs( m13 - m31 ) < epsilon ) &&
|
|
( Math.abs( m23 - m32 ) < epsilon ) ) {
|
|
|
|
// singularity found
|
|
// first check for identity matrix which must have +1 for all terms
|
|
// in leading diagonal and zero in other terms
|
|
|
|
if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
|
|
( Math.abs( m13 + m31 ) < epsilon2 ) &&
|
|
( Math.abs( m23 + m32 ) < epsilon2 ) &&
|
|
( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
|
|
|
|
// this singularity is identity matrix so angle = 0
|
|
|
|
this.set( 1, 0, 0, 0 );
|
|
|
|
return this; // zero angle, arbitrary axis
|
|
|
|
}
|
|
|
|
// otherwise this singularity is angle = 180
|
|
|
|
angle = Math.PI;
|
|
|
|
var xx = ( m11 + 1 ) / 2;
|
|
var yy = ( m22 + 1 ) / 2;
|
|
var zz = ( m33 + 1 ) / 2;
|
|
var xy = ( m12 + m21 ) / 4;
|
|
var xz = ( m13 + m31 ) / 4;
|
|
var yz = ( m23 + m32 ) / 4;
|
|
|
|
if ( ( xx > yy ) && ( xx > zz ) ) {
|
|
|
|
// m11 is the largest diagonal term
|
|
|
|
if ( xx < epsilon ) {
|
|
|
|
x = 0;
|
|
y = 0.707106781;
|
|
z = 0.707106781;
|
|
|
|
} else {
|
|
|
|
x = Math.sqrt( xx );
|
|
y = xy / x;
|
|
z = xz / x;
|
|
|
|
}
|
|
|
|
} else if ( yy > zz ) {
|
|
|
|
// m22 is the largest diagonal term
|
|
|
|
if ( yy < epsilon ) {
|
|
|
|
x = 0.707106781;
|
|
y = 0;
|
|
z = 0.707106781;
|
|
|
|
} else {
|
|
|
|
y = Math.sqrt( yy );
|
|
x = xy / y;
|
|
z = yz / y;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// m33 is the largest diagonal term so base result on this
|
|
|
|
if ( zz < epsilon ) {
|
|
|
|
x = 0.707106781;
|
|
y = 0.707106781;
|
|
z = 0;
|
|
|
|
} else {
|
|
|
|
z = Math.sqrt( zz );
|
|
x = xz / z;
|
|
y = yz / z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.set( x, y, z, angle );
|
|
|
|
return this; // return 180 deg rotation
|
|
|
|
}
|
|
|
|
// as we have reached here there are no singularities so we can handle normally
|
|
|
|
var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
|
|
( m13 - m31 ) * ( m13 - m31 ) +
|
|
( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
|
|
|
|
if ( Math.abs( s ) < 0.001 ) s = 1;
|
|
|
|
// prevent divide by zero, should not happen if matrix is orthogonal and should be
|
|
// caught by singularity test above, but I've left it in just in case
|
|
|
|
this.x = ( m32 - m23 ) / s;
|
|
this.y = ( m13 - m31 ) / s;
|
|
this.z = ( m21 - m12 ) / s;
|
|
this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
min: function ( v ) {
|
|
|
|
this.x = Math.min( this.x, v.x );
|
|
this.y = Math.min( this.y, v.y );
|
|
this.z = Math.min( this.z, v.z );
|
|
this.w = Math.min( this.w, v.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
max: function ( v ) {
|
|
|
|
this.x = Math.max( this.x, v.x );
|
|
this.y = Math.max( this.y, v.y );
|
|
this.z = Math.max( this.z, v.z );
|
|
this.w = Math.max( this.w, v.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clamp: function ( min, max ) {
|
|
|
|
// This function assumes min < max, if this assumption isn't true it will not operate correctly
|
|
|
|
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
|
|
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
|
|
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
|
|
this.w = Math.max( min.w, Math.min( max.w, this.w ) );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clampScalar: function () {
|
|
|
|
var min = new Vector4();
|
|
var max = new Vector4();
|
|
|
|
return function clampScalar( minVal, maxVal ) {
|
|
|
|
min.set( minVal, minVal, minVal, minVal );
|
|
max.set( maxVal, maxVal, maxVal, maxVal );
|
|
|
|
return this.clamp( min, max );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
floor: function () {
|
|
|
|
this.x = Math.floor( this.x );
|
|
this.y = Math.floor( this.y );
|
|
this.z = Math.floor( this.z );
|
|
this.w = Math.floor( this.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
ceil: function () {
|
|
|
|
this.x = Math.ceil( this.x );
|
|
this.y = Math.ceil( this.y );
|
|
this.z = Math.ceil( this.z );
|
|
this.w = Math.ceil( this.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
round: function () {
|
|
|
|
this.x = Math.round( this.x );
|
|
this.y = Math.round( this.y );
|
|
this.z = Math.round( this.z );
|
|
this.w = Math.round( this.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
roundToZero: function () {
|
|
|
|
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
|
|
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
|
|
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
|
|
this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
negate: function () {
|
|
|
|
this.x = - this.x;
|
|
this.y = - this.y;
|
|
this.z = - this.z;
|
|
this.w = - this.w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dot: function ( v ) {
|
|
|
|
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
|
|
|
|
},
|
|
|
|
lengthSq: function () {
|
|
|
|
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
|
|
|
|
},
|
|
|
|
length: function () {
|
|
|
|
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
|
|
|
|
},
|
|
|
|
lengthManhattan: function () {
|
|
|
|
return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
return this.divideScalar( this.length() );
|
|
|
|
},
|
|
|
|
setLength: function ( length ) {
|
|
|
|
return this.multiplyScalar( length / this.length() );
|
|
|
|
},
|
|
|
|
lerp: function ( v, alpha ) {
|
|
|
|
this.x += ( v.x - this.x ) * alpha;
|
|
this.y += ( v.y - this.y ) * alpha;
|
|
this.z += ( v.z - this.z ) * alpha;
|
|
this.w += ( v.w - this.w ) * alpha;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
lerpVectors: function ( v1, v2, alpha ) {
|
|
|
|
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
|
|
|
|
},
|
|
|
|
equals: function ( v ) {
|
|
|
|
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.x = array[ offset ];
|
|
this.y = array[ offset + 1 ];
|
|
this.z = array[ offset + 2 ];
|
|
this.w = array[ offset + 3 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this.x;
|
|
array[ offset + 1 ] = this.y;
|
|
array[ offset + 2 ] = this.z;
|
|
array[ offset + 3 ] = this.w;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
fromBufferAttribute: function ( attribute, index, offset ) {
|
|
|
|
if ( offset !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
|
|
|
|
}
|
|
|
|
this.x = attribute.getX( index );
|
|
this.y = attribute.getY( index );
|
|
this.z = attribute.getZ( index );
|
|
this.w = attribute.getW( index );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author szimek / https://github.com/szimek/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author Marius Kintel / https://github.com/kintel
|
|
*/
|
|
|
|
/*
|
|
In options, we can specify:
|
|
* Texture parameters for an auto-generated target texture
|
|
* depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
|
|
*/
|
|
function WebGLRenderTarget( width, height, options ) {
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
this.scissor = new Vector4( 0, 0, width, height );
|
|
this.scissorTest = false;
|
|
|
|
this.viewport = new Vector4( 0, 0, width, height );
|
|
|
|
options = options || {};
|
|
|
|
if ( options.minFilter === undefined ) options.minFilter = LinearFilter;
|
|
|
|
this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
|
|
|
|
this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
|
|
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
|
|
this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
|
|
|
|
}
|
|
|
|
Object.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {
|
|
|
|
isWebGLRenderTarget: true,
|
|
|
|
setSize: function ( width, height ) {
|
|
|
|
if ( this.width !== width || this.height !== height ) {
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
this.dispose();
|
|
|
|
}
|
|
|
|
this.viewport.set( 0, 0, width, height );
|
|
this.scissor.set( 0, 0, width, height );
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.width = source.width;
|
|
this.height = source.height;
|
|
|
|
this.viewport.copy( source.viewport );
|
|
|
|
this.texture = source.texture.clone();
|
|
|
|
this.depthBuffer = source.depthBuffer;
|
|
this.stencilBuffer = source.stencilBuffer;
|
|
this.depthTexture = source.depthTexture;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dispose: function () {
|
|
|
|
this.dispatchEvent( { type: 'dispose' } );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com
|
|
*/
|
|
|
|
function WebGLRenderTargetCube( width, height, options ) {
|
|
|
|
WebGLRenderTarget.call( this, width, height, options );
|
|
|
|
this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
|
|
this.activeMipMapLevel = 0;
|
|
|
|
}
|
|
|
|
WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );
|
|
WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;
|
|
|
|
WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Quaternion( x, y, z, w ) {
|
|
|
|
this._x = x || 0;
|
|
this._y = y || 0;
|
|
this._z = z || 0;
|
|
this._w = ( w !== undefined ) ? w : 1;
|
|
|
|
}
|
|
|
|
Object.assign( Quaternion, {
|
|
|
|
slerp: function ( qa, qb, qm, t ) {
|
|
|
|
return qm.copy( qa ).slerp( qb, t );
|
|
|
|
},
|
|
|
|
slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
|
|
|
|
// fuzz-free, array-based Quaternion SLERP operation
|
|
|
|
var x0 = src0[ srcOffset0 + 0 ],
|
|
y0 = src0[ srcOffset0 + 1 ],
|
|
z0 = src0[ srcOffset0 + 2 ],
|
|
w0 = src0[ srcOffset0 + 3 ],
|
|
|
|
x1 = src1[ srcOffset1 + 0 ],
|
|
y1 = src1[ srcOffset1 + 1 ],
|
|
z1 = src1[ srcOffset1 + 2 ],
|
|
w1 = src1[ srcOffset1 + 3 ];
|
|
|
|
if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
|
|
|
|
var s = 1 - t,
|
|
|
|
cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
|
|
|
|
dir = ( cos >= 0 ? 1 : - 1 ),
|
|
sqrSin = 1 - cos * cos;
|
|
|
|
// Skip the Slerp for tiny steps to avoid numeric problems:
|
|
if ( sqrSin > Number.EPSILON ) {
|
|
|
|
var sin = Math.sqrt( sqrSin ),
|
|
len = Math.atan2( sin, cos * dir );
|
|
|
|
s = Math.sin( s * len ) / sin;
|
|
t = Math.sin( t * len ) / sin;
|
|
|
|
}
|
|
|
|
var tDir = t * dir;
|
|
|
|
x0 = x0 * s + x1 * tDir;
|
|
y0 = y0 * s + y1 * tDir;
|
|
z0 = z0 * s + z1 * tDir;
|
|
w0 = w0 * s + w1 * tDir;
|
|
|
|
// Normalize in case we just did a lerp:
|
|
if ( s === 1 - t ) {
|
|
|
|
var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
|
|
|
|
x0 *= f;
|
|
y0 *= f;
|
|
z0 *= f;
|
|
w0 *= f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dst[ dstOffset ] = x0;
|
|
dst[ dstOffset + 1 ] = y0;
|
|
dst[ dstOffset + 2 ] = z0;
|
|
dst[ dstOffset + 3 ] = w0;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( Quaternion.prototype, {
|
|
|
|
x: {
|
|
|
|
get: function () {
|
|
|
|
return this._x;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._x = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
y: {
|
|
|
|
get: function () {
|
|
|
|
return this._y;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._y = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
z: {
|
|
|
|
get: function () {
|
|
|
|
return this._z;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._z = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
w: {
|
|
|
|
get: function () {
|
|
|
|
return this._w;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._w = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Quaternion.prototype, {
|
|
|
|
set: function ( x, y, z, w ) {
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
this._w = w;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this._x, this._y, this._z, this._w );
|
|
|
|
},
|
|
|
|
copy: function ( quaternion ) {
|
|
|
|
this._x = quaternion.x;
|
|
this._y = quaternion.y;
|
|
this._z = quaternion.z;
|
|
this._w = quaternion.w;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromEuler: function ( euler, update ) {
|
|
|
|
if ( ( euler && euler.isEuler ) === false ) {
|
|
|
|
throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
|
|
|
|
}
|
|
|
|
var x = euler._x, y = euler._y, z = euler._z, order = euler.order;
|
|
|
|
// http://www.mathworks.com/matlabcentral/fileexchange/
|
|
// 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
|
|
// content/SpinCalc.m
|
|
|
|
var cos = Math.cos;
|
|
var sin = Math.sin;
|
|
|
|
var c1 = cos( x / 2 );
|
|
var c2 = cos( y / 2 );
|
|
var c3 = cos( z / 2 );
|
|
|
|
var s1 = sin( x / 2 );
|
|
var s2 = sin( y / 2 );
|
|
var s3 = sin( z / 2 );
|
|
|
|
if ( order === 'XYZ' ) {
|
|
|
|
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
|
|
} else if ( order === 'YXZ' ) {
|
|
|
|
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
|
|
} else if ( order === 'ZXY' ) {
|
|
|
|
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
|
|
} else if ( order === 'ZYX' ) {
|
|
|
|
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
|
|
} else if ( order === 'YZX' ) {
|
|
|
|
this._x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 - s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 - s1 * s2 * s3;
|
|
|
|
} else if ( order === 'XZY' ) {
|
|
|
|
this._x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
this._y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
this._z = c1 * c2 * s3 + s1 * s2 * c3;
|
|
this._w = c1 * c2 * c3 + s1 * s2 * s3;
|
|
|
|
}
|
|
|
|
if ( update !== false ) this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromAxisAngle: function ( axis, angle ) {
|
|
|
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
|
|
|
|
// assumes axis is normalized
|
|
|
|
var halfAngle = angle / 2, s = Math.sin( halfAngle );
|
|
|
|
this._x = axis.x * s;
|
|
this._y = axis.y * s;
|
|
this._z = axis.z * s;
|
|
this._w = Math.cos( halfAngle );
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromRotationMatrix: function ( m ) {
|
|
|
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
|
|
|
|
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
|
|
var te = m.elements,
|
|
|
|
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
|
|
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
|
|
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
|
|
|
|
trace = m11 + m22 + m33,
|
|
s;
|
|
|
|
if ( trace > 0 ) {
|
|
|
|
s = 0.5 / Math.sqrt( trace + 1.0 );
|
|
|
|
this._w = 0.25 / s;
|
|
this._x = ( m32 - m23 ) * s;
|
|
this._y = ( m13 - m31 ) * s;
|
|
this._z = ( m21 - m12 ) * s;
|
|
|
|
} else if ( m11 > m22 && m11 > m33 ) {
|
|
|
|
s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
|
|
|
|
this._w = ( m32 - m23 ) / s;
|
|
this._x = 0.25 * s;
|
|
this._y = ( m12 + m21 ) / s;
|
|
this._z = ( m13 + m31 ) / s;
|
|
|
|
} else if ( m22 > m33 ) {
|
|
|
|
s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
|
|
|
|
this._w = ( m13 - m31 ) / s;
|
|
this._x = ( m12 + m21 ) / s;
|
|
this._y = 0.25 * s;
|
|
this._z = ( m23 + m32 ) / s;
|
|
|
|
} else {
|
|
|
|
s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
|
|
|
|
this._w = ( m21 - m12 ) / s;
|
|
this._x = ( m13 + m31 ) / s;
|
|
this._y = ( m23 + m32 ) / s;
|
|
this._z = 0.25 * s;
|
|
|
|
}
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromUnitVectors: function () {
|
|
|
|
// assumes direction vectors vFrom and vTo are normalized
|
|
|
|
var v1 = new Vector3();
|
|
var r;
|
|
|
|
var EPS = 0.000001;
|
|
|
|
return function setFromUnitVectors( vFrom, vTo ) {
|
|
|
|
if ( v1 === undefined ) v1 = new Vector3();
|
|
|
|
r = vFrom.dot( vTo ) + 1;
|
|
|
|
if ( r < EPS ) {
|
|
|
|
r = 0;
|
|
|
|
if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
|
|
|
|
v1.set( - vFrom.y, vFrom.x, 0 );
|
|
|
|
} else {
|
|
|
|
v1.set( 0, - vFrom.z, vFrom.y );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
v1.crossVectors( vFrom, vTo );
|
|
|
|
}
|
|
|
|
this._x = v1.x;
|
|
this._y = v1.y;
|
|
this._z = v1.z;
|
|
this._w = r;
|
|
|
|
return this.normalize();
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
inverse: function () {
|
|
|
|
return this.conjugate().normalize();
|
|
|
|
},
|
|
|
|
conjugate: function () {
|
|
|
|
this._x *= - 1;
|
|
this._y *= - 1;
|
|
this._z *= - 1;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dot: function ( v ) {
|
|
|
|
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
|
|
|
|
},
|
|
|
|
lengthSq: function () {
|
|
|
|
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
|
|
|
|
},
|
|
|
|
length: function () {
|
|
|
|
return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
var l = this.length();
|
|
|
|
if ( l === 0 ) {
|
|
|
|
this._x = 0;
|
|
this._y = 0;
|
|
this._z = 0;
|
|
this._w = 1;
|
|
|
|
} else {
|
|
|
|
l = 1 / l;
|
|
|
|
this._x = this._x * l;
|
|
this._y = this._y * l;
|
|
this._z = this._z * l;
|
|
this._w = this._w * l;
|
|
|
|
}
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiply: function ( q, p ) {
|
|
|
|
if ( p !== undefined ) {
|
|
|
|
console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
|
|
return this.multiplyQuaternions( q, p );
|
|
|
|
}
|
|
|
|
return this.multiplyQuaternions( this, q );
|
|
|
|
},
|
|
|
|
premultiply: function ( q ) {
|
|
|
|
return this.multiplyQuaternions( q, this );
|
|
|
|
},
|
|
|
|
multiplyQuaternions: function ( a, b ) {
|
|
|
|
// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
|
|
|
|
var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
|
|
var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
|
|
|
|
this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
|
|
this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
|
|
this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
|
|
this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
slerp: function ( qb, t ) {
|
|
|
|
if ( t === 0 ) return this;
|
|
if ( t === 1 ) return this.copy( qb );
|
|
|
|
var x = this._x, y = this._y, z = this._z, w = this._w;
|
|
|
|
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
|
|
|
|
var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
|
|
|
|
if ( cosHalfTheta < 0 ) {
|
|
|
|
this._w = - qb._w;
|
|
this._x = - qb._x;
|
|
this._y = - qb._y;
|
|
this._z = - qb._z;
|
|
|
|
cosHalfTheta = - cosHalfTheta;
|
|
|
|
} else {
|
|
|
|
this.copy( qb );
|
|
|
|
}
|
|
|
|
if ( cosHalfTheta >= 1.0 ) {
|
|
|
|
this._w = w;
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
|
|
|
|
if ( Math.abs( sinHalfTheta ) < 0.001 ) {
|
|
|
|
this._w = 0.5 * ( w + this._w );
|
|
this._x = 0.5 * ( x + this._x );
|
|
this._y = 0.5 * ( y + this._y );
|
|
this._z = 0.5 * ( z + this._z );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
|
|
var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
|
|
ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
|
|
|
|
this._w = ( w * ratioA + this._w * ratioB );
|
|
this._x = ( x * ratioA + this._x * ratioB );
|
|
this._y = ( y * ratioA + this._y * ratioB );
|
|
this._z = ( z * ratioA + this._z * ratioB );
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( quaternion ) {
|
|
|
|
return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this._x = array[ offset ];
|
|
this._y = array[ offset + 1 ];
|
|
this._z = array[ offset + 2 ];
|
|
this._w = array[ offset + 3 ];
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this._x;
|
|
array[ offset + 1 ] = this._y;
|
|
array[ offset + 2 ] = this._z;
|
|
array[ offset + 3 ] = this._w;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
onChange: function ( callback ) {
|
|
|
|
this.onChangeCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
onChangeCallback: function () {}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author *kile / http://kile.stravaganza.org/
|
|
* @author philogb / http://blog.thejit.org/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author egraether / http://egraether.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function Vector3( x, y, z ) {
|
|
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
|
|
}
|
|
|
|
Object.assign( Vector3.prototype, {
|
|
|
|
isVector3: true,
|
|
|
|
set: function ( x, y, z ) {
|
|
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setScalar: function ( scalar ) {
|
|
|
|
this.x = scalar;
|
|
this.y = scalar;
|
|
this.z = scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setX: function ( x ) {
|
|
|
|
this.x = x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setY: function ( y ) {
|
|
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setZ: function ( z ) {
|
|
|
|
this.z = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setComponent: function ( index, value ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: this.x = value; break;
|
|
case 1: this.y = value; break;
|
|
case 2: this.z = value; break;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getComponent: function ( index ) {
|
|
|
|
switch ( index ) {
|
|
|
|
case 0: return this.x;
|
|
case 1: return this.y;
|
|
case 2: return this.z;
|
|
default: throw new Error( 'index is out of range: ' + index );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.x, this.y, this.z );
|
|
|
|
},
|
|
|
|
copy: function ( v ) {
|
|
|
|
this.x = v.x;
|
|
this.y = v.y;
|
|
this.z = v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
add: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
|
|
return this.addVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x += v.x;
|
|
this.y += v.y;
|
|
this.z += v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScalar: function ( s ) {
|
|
|
|
this.x += s;
|
|
this.y += s;
|
|
this.z += s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addVectors: function ( a, b ) {
|
|
|
|
this.x = a.x + b.x;
|
|
this.y = a.y + b.y;
|
|
this.z = a.z + b.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScaledVector: function ( v, s ) {
|
|
|
|
this.x += v.x * s;
|
|
this.y += v.y * s;
|
|
this.z += v.z * s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
sub: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
|
|
return this.subVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x -= v.x;
|
|
this.y -= v.y;
|
|
this.z -= v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subScalar: function ( s ) {
|
|
|
|
this.x -= s;
|
|
this.y -= s;
|
|
this.z -= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
subVectors: function ( a, b ) {
|
|
|
|
this.x = a.x - b.x;
|
|
this.y = a.y - b.y;
|
|
this.z = a.z - b.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiply: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
|
|
return this.multiplyVectors( v, w );
|
|
|
|
}
|
|
|
|
this.x *= v.x;
|
|
this.y *= v.y;
|
|
this.z *= v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( scalar ) {
|
|
|
|
this.x *= scalar;
|
|
this.y *= scalar;
|
|
this.z *= scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyVectors: function ( a, b ) {
|
|
|
|
this.x = a.x * b.x;
|
|
this.y = a.y * b.y;
|
|
this.z = a.z * b.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyEuler: function () {
|
|
|
|
var quaternion = new Quaternion();
|
|
|
|
return function applyEuler( euler ) {
|
|
|
|
if ( ( euler && euler.isEuler ) === false ) {
|
|
|
|
console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
|
|
|
|
}
|
|
|
|
return this.applyQuaternion( quaternion.setFromEuler( euler ) );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
applyAxisAngle: function () {
|
|
|
|
var quaternion = new Quaternion();
|
|
|
|
return function applyAxisAngle( axis, angle ) {
|
|
|
|
return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
applyMatrix3: function ( m ) {
|
|
|
|
var x = this.x, y = this.y, z = this.z;
|
|
var e = m.elements;
|
|
|
|
this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
|
|
this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
|
|
this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyMatrix4: function ( m ) {
|
|
|
|
var x = this.x, y = this.y, z = this.z;
|
|
var e = m.elements;
|
|
|
|
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];
|
|
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];
|
|
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];
|
|
var w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];
|
|
|
|
return this.divideScalar( w );
|
|
|
|
},
|
|
|
|
applyQuaternion: function ( q ) {
|
|
|
|
var x = this.x, y = this.y, z = this.z;
|
|
var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
|
|
|
// calculate quat * vector
|
|
|
|
var ix = qw * x + qy * z - qz * y;
|
|
var iy = qw * y + qz * x - qx * z;
|
|
var iz = qw * z + qx * y - qy * x;
|
|
var iw = - qx * x - qy * y - qz * z;
|
|
|
|
// calculate result * inverse quat
|
|
|
|
this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
|
|
this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
|
|
this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
project: function () {
|
|
|
|
var matrix = new Matrix4();
|
|
|
|
return function project( camera ) {
|
|
|
|
matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
|
|
return this.applyMatrix4( matrix );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
unproject: function () {
|
|
|
|
var matrix = new Matrix4();
|
|
|
|
return function unproject( camera ) {
|
|
|
|
matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
|
|
return this.applyMatrix4( matrix );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
transformDirection: function ( m ) {
|
|
|
|
// input: THREE.Matrix4 affine matrix
|
|
// vector interpreted as a direction
|
|
|
|
var x = this.x, y = this.y, z = this.z;
|
|
var e = m.elements;
|
|
|
|
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
|
|
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
|
|
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
|
|
|
|
return this.normalize();
|
|
|
|
},
|
|
|
|
divide: function ( v ) {
|
|
|
|
this.x /= v.x;
|
|
this.y /= v.y;
|
|
this.z /= v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
divideScalar: function ( scalar ) {
|
|
|
|
return this.multiplyScalar( 1 / scalar );
|
|
|
|
},
|
|
|
|
min: function ( v ) {
|
|
|
|
this.x = Math.min( this.x, v.x );
|
|
this.y = Math.min( this.y, v.y );
|
|
this.z = Math.min( this.z, v.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
max: function ( v ) {
|
|
|
|
this.x = Math.max( this.x, v.x );
|
|
this.y = Math.max( this.y, v.y );
|
|
this.z = Math.max( this.z, v.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clamp: function ( min, max ) {
|
|
|
|
// This function assumes min < max, if this assumption isn't true it will not operate correctly
|
|
|
|
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
|
|
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
|
|
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clampScalar: function () {
|
|
|
|
var min = new Vector3();
|
|
var max = new Vector3();
|
|
|
|
return function clampScalar( minVal, maxVal ) {
|
|
|
|
min.set( minVal, minVal, minVal );
|
|
max.set( maxVal, maxVal, maxVal );
|
|
|
|
return this.clamp( min, max );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clampLength: function ( min, max ) {
|
|
|
|
var length = this.length();
|
|
|
|
return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
|
|
|
|
},
|
|
|
|
floor: function () {
|
|
|
|
this.x = Math.floor( this.x );
|
|
this.y = Math.floor( this.y );
|
|
this.z = Math.floor( this.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
ceil: function () {
|
|
|
|
this.x = Math.ceil( this.x );
|
|
this.y = Math.ceil( this.y );
|
|
this.z = Math.ceil( this.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
round: function () {
|
|
|
|
this.x = Math.round( this.x );
|
|
this.y = Math.round( this.y );
|
|
this.z = Math.round( this.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
roundToZero: function () {
|
|
|
|
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
|
|
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
|
|
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
negate: function () {
|
|
|
|
this.x = - this.x;
|
|
this.y = - this.y;
|
|
this.z = - this.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dot: function ( v ) {
|
|
|
|
return this.x * v.x + this.y * v.y + this.z * v.z;
|
|
|
|
},
|
|
|
|
// TODO lengthSquared?
|
|
|
|
lengthSq: function () {
|
|
|
|
return this.x * this.x + this.y * this.y + this.z * this.z;
|
|
|
|
},
|
|
|
|
length: function () {
|
|
|
|
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
|
|
|
|
},
|
|
|
|
lengthManhattan: function () {
|
|
|
|
return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
return this.divideScalar( this.length() );
|
|
|
|
},
|
|
|
|
setLength: function ( length ) {
|
|
|
|
return this.multiplyScalar( length / this.length() );
|
|
|
|
},
|
|
|
|
lerp: function ( v, alpha ) {
|
|
|
|
this.x += ( v.x - this.x ) * alpha;
|
|
this.y += ( v.y - this.y ) * alpha;
|
|
this.z += ( v.z - this.z ) * alpha;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
lerpVectors: function ( v1, v2, alpha ) {
|
|
|
|
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
|
|
|
|
},
|
|
|
|
cross: function ( v, w ) {
|
|
|
|
if ( w !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
|
|
return this.crossVectors( v, w );
|
|
|
|
}
|
|
|
|
var x = this.x, y = this.y, z = this.z;
|
|
|
|
this.x = y * v.z - z * v.y;
|
|
this.y = z * v.x - x * v.z;
|
|
this.z = x * v.y - y * v.x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
crossVectors: function ( a, b ) {
|
|
|
|
var ax = a.x, ay = a.y, az = a.z;
|
|
var bx = b.x, by = b.y, bz = b.z;
|
|
|
|
this.x = ay * bz - az * by;
|
|
this.y = az * bx - ax * bz;
|
|
this.z = ax * by - ay * bx;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
projectOnVector: function ( vector ) {
|
|
|
|
var scalar = vector.dot( this ) / vector.lengthSq();
|
|
|
|
return this.copy( vector ).multiplyScalar( scalar );
|
|
|
|
},
|
|
|
|
projectOnPlane: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function projectOnPlane( planeNormal ) {
|
|
|
|
v1.copy( this ).projectOnVector( planeNormal );
|
|
|
|
return this.sub( v1 );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
reflect: function () {
|
|
|
|
// reflect incident vector off plane orthogonal to normal
|
|
// normal is assumed to have unit length
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function reflect( normal ) {
|
|
|
|
return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
angleTo: function ( v ) {
|
|
|
|
var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
|
|
|
|
// clamp, to handle numerical problems
|
|
|
|
return Math.acos( _Math.clamp( theta, - 1, 1 ) );
|
|
|
|
},
|
|
|
|
distanceTo: function ( v ) {
|
|
|
|
return Math.sqrt( this.distanceToSquared( v ) );
|
|
|
|
},
|
|
|
|
distanceToSquared: function ( v ) {
|
|
|
|
var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
|
|
|
|
return dx * dx + dy * dy + dz * dz;
|
|
|
|
},
|
|
|
|
distanceToManhattan: function ( v ) {
|
|
|
|
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
|
|
|
|
},
|
|
|
|
setFromSpherical: function ( s ) {
|
|
|
|
var sinPhiRadius = Math.sin( s.phi ) * s.radius;
|
|
|
|
this.x = sinPhiRadius * Math.sin( s.theta );
|
|
this.y = Math.cos( s.phi ) * s.radius;
|
|
this.z = sinPhiRadius * Math.cos( s.theta );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromCylindrical: function ( c ) {
|
|
|
|
this.x = c.radius * Math.sin( c.theta );
|
|
this.y = c.y;
|
|
this.z = c.radius * Math.cos( c.theta );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromMatrixPosition: function ( m ) {
|
|
|
|
return this.setFromMatrixColumn( m, 3 );
|
|
|
|
},
|
|
|
|
setFromMatrixScale: function ( m ) {
|
|
|
|
var sx = this.setFromMatrixColumn( m, 0 ).length();
|
|
var sy = this.setFromMatrixColumn( m, 1 ).length();
|
|
var sz = this.setFromMatrixColumn( m, 2 ).length();
|
|
|
|
this.x = sx;
|
|
this.y = sy;
|
|
this.z = sz;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromMatrixColumn: function ( m, index ) {
|
|
|
|
|
|
return this.fromArray( m.elements, index * 4 );
|
|
|
|
},
|
|
|
|
equals: function ( v ) {
|
|
|
|
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.x = array[ offset ];
|
|
this.y = array[ offset + 1 ];
|
|
this.z = array[ offset + 2 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this.x;
|
|
array[ offset + 1 ] = this.y;
|
|
array[ offset + 2 ] = this.z;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
fromBufferAttribute: function ( attribute, index, offset ) {
|
|
|
|
if ( offset !== undefined ) {
|
|
|
|
console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
|
|
|
|
}
|
|
|
|
this.x = attribute.getX( index );
|
|
this.y = attribute.getY( index );
|
|
this.z = attribute.getZ( index );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author supereggbert / http://www.paulbrunt.co.uk/
|
|
* @author philogb / http://blog.thejit.org/
|
|
* @author jordi_ros / http://plattsoft.com
|
|
* @author D1plo1d / http://github.com/D1plo1d
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author timknip / http://www.floorplanner.com/
|
|
* @author bhouston / http://clara.io
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function Matrix4() {
|
|
|
|
this.elements = [
|
|
|
|
1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
|
|
];
|
|
|
|
if ( arguments.length > 0 ) {
|
|
|
|
console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Object.assign( Matrix4.prototype, {
|
|
|
|
isMatrix4: true,
|
|
|
|
set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
|
|
|
|
var te = this.elements;
|
|
|
|
te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
|
|
te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
|
|
te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
|
|
te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
identity: function () {
|
|
|
|
this.set(
|
|
|
|
1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new Matrix4().fromArray( this.elements );
|
|
|
|
},
|
|
|
|
copy: function ( m ) {
|
|
|
|
var te = this.elements;
|
|
var me = m.elements;
|
|
|
|
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
|
|
te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
|
|
te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
|
|
te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyPosition: function ( m ) {
|
|
|
|
var te = this.elements, me = m.elements;
|
|
|
|
te[ 12 ] = me[ 12 ];
|
|
te[ 13 ] = me[ 13 ];
|
|
te[ 14 ] = me[ 14 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
extractBasis: function ( xAxis, yAxis, zAxis ) {
|
|
|
|
xAxis.setFromMatrixColumn( this, 0 );
|
|
yAxis.setFromMatrixColumn( this, 1 );
|
|
zAxis.setFromMatrixColumn( this, 2 );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeBasis: function ( xAxis, yAxis, zAxis ) {
|
|
|
|
this.set(
|
|
xAxis.x, yAxis.x, zAxis.x, 0,
|
|
xAxis.y, yAxis.y, zAxis.y, 0,
|
|
xAxis.z, yAxis.z, zAxis.z, 0,
|
|
0, 0, 0, 1
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
extractRotation: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function extractRotation( m ) {
|
|
|
|
var te = this.elements;
|
|
var me = m.elements;
|
|
|
|
var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();
|
|
var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();
|
|
var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();
|
|
|
|
te[ 0 ] = me[ 0 ] * scaleX;
|
|
te[ 1 ] = me[ 1 ] * scaleX;
|
|
te[ 2 ] = me[ 2 ] * scaleX;
|
|
|
|
te[ 4 ] = me[ 4 ] * scaleY;
|
|
te[ 5 ] = me[ 5 ] * scaleY;
|
|
te[ 6 ] = me[ 6 ] * scaleY;
|
|
|
|
te[ 8 ] = me[ 8 ] * scaleZ;
|
|
te[ 9 ] = me[ 9 ] * scaleZ;
|
|
te[ 10 ] = me[ 10 ] * scaleZ;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
makeRotationFromEuler: function ( euler ) {
|
|
|
|
if ( ( euler && euler.isEuler ) === false ) {
|
|
|
|
console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
|
|
|
|
}
|
|
|
|
var te = this.elements;
|
|
|
|
var x = euler.x, y = euler.y, z = euler.z;
|
|
var a = Math.cos( x ), b = Math.sin( x );
|
|
var c = Math.cos( y ), d = Math.sin( y );
|
|
var e = Math.cos( z ), f = Math.sin( z );
|
|
|
|
if ( euler.order === 'XYZ' ) {
|
|
|
|
var ae = a * e, af = a * f, be = b * e, bf = b * f;
|
|
|
|
te[ 0 ] = c * e;
|
|
te[ 4 ] = - c * f;
|
|
te[ 8 ] = d;
|
|
|
|
te[ 1 ] = af + be * d;
|
|
te[ 5 ] = ae - bf * d;
|
|
te[ 9 ] = - b * c;
|
|
|
|
te[ 2 ] = bf - ae * d;
|
|
te[ 6 ] = be + af * d;
|
|
te[ 10 ] = a * c;
|
|
|
|
} else if ( euler.order === 'YXZ' ) {
|
|
|
|
var ce = c * e, cf = c * f, de = d * e, df = d * f;
|
|
|
|
te[ 0 ] = ce + df * b;
|
|
te[ 4 ] = de * b - cf;
|
|
te[ 8 ] = a * d;
|
|
|
|
te[ 1 ] = a * f;
|
|
te[ 5 ] = a * e;
|
|
te[ 9 ] = - b;
|
|
|
|
te[ 2 ] = cf * b - de;
|
|
te[ 6 ] = df + ce * b;
|
|
te[ 10 ] = a * c;
|
|
|
|
} else if ( euler.order === 'ZXY' ) {
|
|
|
|
var ce = c * e, cf = c * f, de = d * e, df = d * f;
|
|
|
|
te[ 0 ] = ce - df * b;
|
|
te[ 4 ] = - a * f;
|
|
te[ 8 ] = de + cf * b;
|
|
|
|
te[ 1 ] = cf + de * b;
|
|
te[ 5 ] = a * e;
|
|
te[ 9 ] = df - ce * b;
|
|
|
|
te[ 2 ] = - a * d;
|
|
te[ 6 ] = b;
|
|
te[ 10 ] = a * c;
|
|
|
|
} else if ( euler.order === 'ZYX' ) {
|
|
|
|
var ae = a * e, af = a * f, be = b * e, bf = b * f;
|
|
|
|
te[ 0 ] = c * e;
|
|
te[ 4 ] = be * d - af;
|
|
te[ 8 ] = ae * d + bf;
|
|
|
|
te[ 1 ] = c * f;
|
|
te[ 5 ] = bf * d + ae;
|
|
te[ 9 ] = af * d - be;
|
|
|
|
te[ 2 ] = - d;
|
|
te[ 6 ] = b * c;
|
|
te[ 10 ] = a * c;
|
|
|
|
} else if ( euler.order === 'YZX' ) {
|
|
|
|
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
|
|
|
|
te[ 0 ] = c * e;
|
|
te[ 4 ] = bd - ac * f;
|
|
te[ 8 ] = bc * f + ad;
|
|
|
|
te[ 1 ] = f;
|
|
te[ 5 ] = a * e;
|
|
te[ 9 ] = - b * e;
|
|
|
|
te[ 2 ] = - d * e;
|
|
te[ 6 ] = ad * f + bc;
|
|
te[ 10 ] = ac - bd * f;
|
|
|
|
} else if ( euler.order === 'XZY' ) {
|
|
|
|
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
|
|
|
|
te[ 0 ] = c * e;
|
|
te[ 4 ] = - f;
|
|
te[ 8 ] = d * e;
|
|
|
|
te[ 1 ] = ac * f + bd;
|
|
te[ 5 ] = a * e;
|
|
te[ 9 ] = ad * f - bc;
|
|
|
|
te[ 2 ] = bc * f - ad;
|
|
te[ 6 ] = b * e;
|
|
te[ 10 ] = bd * f + ac;
|
|
|
|
}
|
|
|
|
// last column
|
|
te[ 3 ] = 0;
|
|
te[ 7 ] = 0;
|
|
te[ 11 ] = 0;
|
|
|
|
// bottom row
|
|
te[ 12 ] = 0;
|
|
te[ 13 ] = 0;
|
|
te[ 14 ] = 0;
|
|
te[ 15 ] = 1;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeRotationFromQuaternion: function ( q ) {
|
|
|
|
var te = this.elements;
|
|
|
|
var x = q._x, y = q._y, z = q._z, w = q._w;
|
|
var x2 = x + x, y2 = y + y, z2 = z + z;
|
|
var xx = x * x2, xy = x * y2, xz = x * z2;
|
|
var yy = y * y2, yz = y * z2, zz = z * z2;
|
|
var wx = w * x2, wy = w * y2, wz = w * z2;
|
|
|
|
te[ 0 ] = 1 - ( yy + zz );
|
|
te[ 4 ] = xy - wz;
|
|
te[ 8 ] = xz + wy;
|
|
|
|
te[ 1 ] = xy + wz;
|
|
te[ 5 ] = 1 - ( xx + zz );
|
|
te[ 9 ] = yz - wx;
|
|
|
|
te[ 2 ] = xz - wy;
|
|
te[ 6 ] = yz + wx;
|
|
te[ 10 ] = 1 - ( xx + yy );
|
|
|
|
// last column
|
|
te[ 3 ] = 0;
|
|
te[ 7 ] = 0;
|
|
te[ 11 ] = 0;
|
|
|
|
// bottom row
|
|
te[ 12 ] = 0;
|
|
te[ 13 ] = 0;
|
|
te[ 14 ] = 0;
|
|
te[ 15 ] = 1;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
lookAt: function () {
|
|
|
|
var x = new Vector3();
|
|
var y = new Vector3();
|
|
var z = new Vector3();
|
|
|
|
return function lookAt( eye, target, up ) {
|
|
|
|
var te = this.elements;
|
|
|
|
z.subVectors( eye, target );
|
|
|
|
if ( z.lengthSq() === 0 ) {
|
|
|
|
// eye and target are in the same position
|
|
|
|
z.z = 1;
|
|
|
|
}
|
|
|
|
z.normalize();
|
|
x.crossVectors( up, z );
|
|
|
|
if ( x.lengthSq() === 0 ) {
|
|
|
|
// eye and target are in the same vertical
|
|
|
|
z.z += 0.0001;
|
|
x.crossVectors( up, z );
|
|
|
|
}
|
|
|
|
x.normalize();
|
|
y.crossVectors( z, x );
|
|
|
|
te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
|
|
te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
|
|
te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
multiply: function ( m, n ) {
|
|
|
|
if ( n !== undefined ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
|
|
return this.multiplyMatrices( m, n );
|
|
|
|
}
|
|
|
|
return this.multiplyMatrices( this, m );
|
|
|
|
},
|
|
|
|
premultiply: function ( m ) {
|
|
|
|
return this.multiplyMatrices( m, this );
|
|
|
|
},
|
|
|
|
multiplyMatrices: function ( a, b ) {
|
|
|
|
var ae = a.elements;
|
|
var be = b.elements;
|
|
var te = this.elements;
|
|
|
|
var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
|
|
var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
|
|
var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
|
|
var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
|
|
|
|
var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
|
|
var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
|
|
var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
|
|
var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
|
|
|
|
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
|
|
te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
|
|
te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
|
|
te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
|
|
|
|
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
|
|
te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
|
|
te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
|
|
te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
|
|
|
|
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
|
|
te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
|
|
te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
|
|
te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
|
|
|
|
te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
|
|
te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
|
|
te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
|
|
te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( s ) {
|
|
|
|
var te = this.elements;
|
|
|
|
te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
|
|
te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
|
|
te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
|
|
te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyToBufferAttribute: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function applyToBufferAttribute( attribute ) {
|
|
|
|
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
|
|
|
|
v1.x = attribute.getX( i );
|
|
v1.y = attribute.getY( i );
|
|
v1.z = attribute.getZ( i );
|
|
|
|
v1.applyMatrix4( this );
|
|
|
|
attribute.setXYZ( i, v1.x, v1.y, v1.z );
|
|
|
|
}
|
|
|
|
return attribute;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
determinant: function () {
|
|
|
|
var te = this.elements;
|
|
|
|
var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
|
|
var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
|
|
var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
|
|
var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
|
|
|
|
//TODO: make this more efficient
|
|
//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
|
|
|
|
return (
|
|
n41 * (
|
|
+ n14 * n23 * n32
|
|
- n13 * n24 * n32
|
|
- n14 * n22 * n33
|
|
+ n12 * n24 * n33
|
|
+ n13 * n22 * n34
|
|
- n12 * n23 * n34
|
|
) +
|
|
n42 * (
|
|
+ n11 * n23 * n34
|
|
- n11 * n24 * n33
|
|
+ n14 * n21 * n33
|
|
- n13 * n21 * n34
|
|
+ n13 * n24 * n31
|
|
- n14 * n23 * n31
|
|
) +
|
|
n43 * (
|
|
+ n11 * n24 * n32
|
|
- n11 * n22 * n34
|
|
- n14 * n21 * n32
|
|
+ n12 * n21 * n34
|
|
+ n14 * n22 * n31
|
|
- n12 * n24 * n31
|
|
) +
|
|
n44 * (
|
|
- n13 * n22 * n31
|
|
- n11 * n23 * n32
|
|
+ n11 * n22 * n33
|
|
+ n13 * n21 * n32
|
|
- n12 * n21 * n33
|
|
+ n12 * n23 * n31
|
|
)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
transpose: function () {
|
|
|
|
var te = this.elements;
|
|
var tmp;
|
|
|
|
tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
|
|
tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
|
|
tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
|
|
|
|
tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
|
|
tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
|
|
tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setPosition: function ( v ) {
|
|
|
|
var te = this.elements;
|
|
|
|
te[ 12 ] = v.x;
|
|
te[ 13 ] = v.y;
|
|
te[ 14 ] = v.z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getInverse: function ( m, throwOnDegenerate ) {
|
|
|
|
// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
|
|
var te = this.elements,
|
|
me = m.elements,
|
|
|
|
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
|
|
n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
|
|
n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
|
|
n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
|
|
|
|
t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
|
|
t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
|
|
t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
|
|
t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
|
|
|
|
var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
|
|
|
|
if ( det === 0 ) {
|
|
|
|
var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
|
|
|
|
if ( throwOnDegenerate === true ) {
|
|
|
|
throw new Error( msg );
|
|
|
|
} else {
|
|
|
|
console.warn( msg );
|
|
|
|
}
|
|
|
|
return this.identity();
|
|
|
|
}
|
|
|
|
var detInv = 1 / det;
|
|
|
|
te[ 0 ] = t11 * detInv;
|
|
te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
|
|
te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
|
|
te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
|
|
|
|
te[ 4 ] = t12 * detInv;
|
|
te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
|
|
te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
|
|
te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
|
|
|
|
te[ 8 ] = t13 * detInv;
|
|
te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
|
|
te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
|
|
te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
|
|
|
|
te[ 12 ] = t14 * detInv;
|
|
te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
|
|
te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
|
|
te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
scale: function ( v ) {
|
|
|
|
var te = this.elements;
|
|
var x = v.x, y = v.y, z = v.z;
|
|
|
|
te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
|
|
te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
|
|
te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
|
|
te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getMaxScaleOnAxis: function () {
|
|
|
|
var te = this.elements;
|
|
|
|
var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
|
|
var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
|
|
var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
|
|
|
|
return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
|
|
|
|
},
|
|
|
|
makeTranslation: function ( x, y, z ) {
|
|
|
|
this.set(
|
|
|
|
1, 0, 0, x,
|
|
0, 1, 0, y,
|
|
0, 0, 1, z,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeRotationX: function ( theta ) {
|
|
|
|
var c = Math.cos( theta ), s = Math.sin( theta );
|
|
|
|
this.set(
|
|
|
|
1, 0, 0, 0,
|
|
0, c, - s, 0,
|
|
0, s, c, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeRotationY: function ( theta ) {
|
|
|
|
var c = Math.cos( theta ), s = Math.sin( theta );
|
|
|
|
this.set(
|
|
|
|
c, 0, s, 0,
|
|
0, 1, 0, 0,
|
|
- s, 0, c, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeRotationZ: function ( theta ) {
|
|
|
|
var c = Math.cos( theta ), s = Math.sin( theta );
|
|
|
|
this.set(
|
|
|
|
c, - s, 0, 0,
|
|
s, c, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeRotationAxis: function ( axis, angle ) {
|
|
|
|
// Based on http://www.gamedev.net/reference/articles/article1199.asp
|
|
|
|
var c = Math.cos( angle );
|
|
var s = Math.sin( angle );
|
|
var t = 1 - c;
|
|
var x = axis.x, y = axis.y, z = axis.z;
|
|
var tx = t * x, ty = t * y;
|
|
|
|
this.set(
|
|
|
|
tx * x + c, tx * y - s * z, tx * z + s * y, 0,
|
|
tx * y + s * z, ty * y + c, ty * z - s * x, 0,
|
|
tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeScale: function ( x, y, z ) {
|
|
|
|
this.set(
|
|
|
|
x, 0, 0, 0,
|
|
0, y, 0, 0,
|
|
0, 0, z, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeShear: function ( x, y, z ) {
|
|
|
|
this.set(
|
|
|
|
1, y, z, 0,
|
|
x, 1, z, 0,
|
|
x, y, 1, 0,
|
|
0, 0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
compose: function ( position, quaternion, scale ) {
|
|
|
|
this.makeRotationFromQuaternion( quaternion );
|
|
this.scale( scale );
|
|
this.setPosition( position );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
decompose: function () {
|
|
|
|
var vector = new Vector3();
|
|
var matrix = new Matrix4();
|
|
|
|
return function decompose( position, quaternion, scale ) {
|
|
|
|
var te = this.elements;
|
|
|
|
var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
|
|
var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
|
|
var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
|
|
|
|
// if determine is negative, we need to invert one scale
|
|
var det = this.determinant();
|
|
if ( det < 0 ) sx = - sx;
|
|
|
|
position.x = te[ 12 ];
|
|
position.y = te[ 13 ];
|
|
position.z = te[ 14 ];
|
|
|
|
// scale the rotation part
|
|
matrix.copy( this );
|
|
|
|
var invSX = 1 / sx;
|
|
var invSY = 1 / sy;
|
|
var invSZ = 1 / sz;
|
|
|
|
matrix.elements[ 0 ] *= invSX;
|
|
matrix.elements[ 1 ] *= invSX;
|
|
matrix.elements[ 2 ] *= invSX;
|
|
|
|
matrix.elements[ 4 ] *= invSY;
|
|
matrix.elements[ 5 ] *= invSY;
|
|
matrix.elements[ 6 ] *= invSY;
|
|
|
|
matrix.elements[ 8 ] *= invSZ;
|
|
matrix.elements[ 9 ] *= invSZ;
|
|
matrix.elements[ 10 ] *= invSZ;
|
|
|
|
quaternion.setFromRotationMatrix( matrix );
|
|
|
|
scale.x = sx;
|
|
scale.y = sy;
|
|
scale.z = sz;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
makePerspective: function ( left, right, top, bottom, near, far ) {
|
|
|
|
if ( far === undefined ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
|
|
|
|
}
|
|
|
|
var te = this.elements;
|
|
var x = 2 * near / ( right - left );
|
|
var y = 2 * near / ( top - bottom );
|
|
|
|
var a = ( right + left ) / ( right - left );
|
|
var b = ( top + bottom ) / ( top - bottom );
|
|
var c = - ( far + near ) / ( far - near );
|
|
var d = - 2 * far * near / ( far - near );
|
|
|
|
te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
|
|
te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
|
|
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
|
|
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeOrthographic: function ( left, right, top, bottom, near, far ) {
|
|
|
|
var te = this.elements;
|
|
var w = 1.0 / ( right - left );
|
|
var h = 1.0 / ( top - bottom );
|
|
var p = 1.0 / ( far - near );
|
|
|
|
var x = ( right + left ) * w;
|
|
var y = ( top + bottom ) * h;
|
|
var z = ( far + near ) * p;
|
|
|
|
te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
|
|
te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
|
|
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
|
|
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( matrix ) {
|
|
|
|
var te = this.elements;
|
|
var me = matrix.elements;
|
|
|
|
for ( var i = 0; i < 16; i ++ ) {
|
|
|
|
if ( te[ i ] !== me[ i ] ) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
for ( var i = 0; i < 16; i ++ ) {
|
|
|
|
this.elements[ i ] = array[ i + offset ];
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
var te = this.elements;
|
|
|
|
array[ offset ] = te[ 0 ];
|
|
array[ offset + 1 ] = te[ 1 ];
|
|
array[ offset + 2 ] = te[ 2 ];
|
|
array[ offset + 3 ] = te[ 3 ];
|
|
|
|
array[ offset + 4 ] = te[ 4 ];
|
|
array[ offset + 5 ] = te[ 5 ];
|
|
array[ offset + 6 ] = te[ 6 ];
|
|
array[ offset + 7 ] = te[ 7 ];
|
|
|
|
array[ offset + 8 ] = te[ 8 ];
|
|
array[ offset + 9 ] = te[ 9 ];
|
|
array[ offset + 10 ] = te[ 10 ];
|
|
array[ offset + 11 ] = te[ 11 ];
|
|
|
|
array[ offset + 12 ] = te[ 12 ];
|
|
array[ offset + 13 ] = te[ 13 ];
|
|
array[ offset + 14 ] = te[ 14 ];
|
|
array[ offset + 15 ] = te[ 15 ];
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
|
|
|
|
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
|
|
|
|
this.image = { data: data, width: width, height: height };
|
|
|
|
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
|
|
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
|
|
|
|
this.generateMipmaps = false;
|
|
this.flipY = false;
|
|
this.unpackAlignment = 1;
|
|
|
|
}
|
|
|
|
DataTexture.prototype = Object.create( Texture.prototype );
|
|
DataTexture.prototype.constructor = DataTexture;
|
|
|
|
DataTexture.prototype.isDataTexture = true;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
|
|
|
|
images = images !== undefined ? images : [];
|
|
mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
|
|
|
|
Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
|
|
|
|
this.flipY = false;
|
|
|
|
}
|
|
|
|
CubeTexture.prototype = Object.create( Texture.prototype );
|
|
CubeTexture.prototype.constructor = CubeTexture;
|
|
|
|
CubeTexture.prototype.isCubeTexture = true;
|
|
|
|
Object.defineProperty( CubeTexture.prototype, 'images', {
|
|
|
|
get: function () {
|
|
|
|
return this.image;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this.image = value;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author tschw
|
|
*
|
|
* Uniforms of a program.
|
|
* Those form a tree structure with a special top-level container for the root,
|
|
* which you get by calling 'new WebGLUniforms( gl, program, renderer )'.
|
|
*
|
|
*
|
|
* Properties of inner nodes including the top-level container:
|
|
*
|
|
* .seq - array of nested uniforms
|
|
* .map - nested uniforms by name
|
|
*
|
|
*
|
|
* Methods of all nodes except the top-level container:
|
|
*
|
|
* .setValue( gl, value, [renderer] )
|
|
*
|
|
* uploads a uniform value(s)
|
|
* the 'renderer' parameter is needed for sampler uniforms
|
|
*
|
|
*
|
|
* Static methods of the top-level container (renderer factorizations):
|
|
*
|
|
* .upload( gl, seq, values, renderer )
|
|
*
|
|
* sets uniforms in 'seq' to 'values[id].value'
|
|
*
|
|
* .seqWithValue( seq, values ) : filteredSeq
|
|
*
|
|
* filters 'seq' entries with corresponding entry in values
|
|
*
|
|
*
|
|
* Methods of the top-level container (renderer factorizations):
|
|
*
|
|
* .setValue( gl, name, value )
|
|
*
|
|
* sets uniform with name 'name' to 'value'
|
|
*
|
|
* .set( gl, obj, prop )
|
|
*
|
|
* sets uniform from object and property with same name than uniform
|
|
*
|
|
* .setOptional( gl, obj, prop )
|
|
*
|
|
* like .set for an optional property of the object
|
|
*
|
|
*/
|
|
|
|
var emptyTexture = new Texture();
|
|
var emptyCubeTexture = new CubeTexture();
|
|
|
|
// --- Base for inner nodes (including the root) ---
|
|
|
|
function UniformContainer() {
|
|
|
|
this.seq = [];
|
|
this.map = {};
|
|
|
|
}
|
|
|
|
// --- Utilities ---
|
|
|
|
// Array Caches (provide typed arrays for temporary by size)
|
|
|
|
var arrayCacheF32 = [];
|
|
var arrayCacheI32 = [];
|
|
|
|
// Float32Array caches used for uploading Matrix uniforms
|
|
|
|
var mat4array = new Float32Array( 16 );
|
|
var mat3array = new Float32Array( 9 );
|
|
|
|
// Flattening for arrays of vectors and matrices
|
|
|
|
function flatten( array, nBlocks, blockSize ) {
|
|
|
|
var firstElem = array[ 0 ];
|
|
|
|
if ( firstElem <= 0 || firstElem > 0 ) return array;
|
|
// unoptimized: ! isNaN( firstElem )
|
|
// see http://jacksondunstan.com/articles/983
|
|
|
|
var n = nBlocks * blockSize,
|
|
r = arrayCacheF32[ n ];
|
|
|
|
if ( r === undefined ) {
|
|
|
|
r = new Float32Array( n );
|
|
arrayCacheF32[ n ] = r;
|
|
|
|
}
|
|
|
|
if ( nBlocks !== 0 ) {
|
|
|
|
firstElem.toArray( r, 0 );
|
|
|
|
for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
|
|
|
|
offset += blockSize;
|
|
array[ i ].toArray( r, offset );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
// Texture unit allocation
|
|
|
|
function allocTexUnits( renderer, n ) {
|
|
|
|
var r = arrayCacheI32[ n ];
|
|
|
|
if ( r === undefined ) {
|
|
|
|
r = new Int32Array( n );
|
|
arrayCacheI32[ n ] = r;
|
|
|
|
}
|
|
|
|
for ( var i = 0; i !== n; ++ i )
|
|
r[ i ] = renderer.allocTextureUnit();
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
// --- Setters ---
|
|
|
|
// Note: Defining these methods externally, because they come in a bunch
|
|
// and this way their names minify.
|
|
|
|
// Single scalar
|
|
|
|
function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
|
|
function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
|
|
|
|
// Single float vector (from flat array or THREE.VectorN)
|
|
|
|
function setValue2fv( gl, v ) {
|
|
|
|
if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
|
|
else gl.uniform2f( this.addr, v.x, v.y );
|
|
|
|
}
|
|
|
|
function setValue3fv( gl, v ) {
|
|
|
|
if ( v.x !== undefined )
|
|
gl.uniform3f( this.addr, v.x, v.y, v.z );
|
|
else if ( v.r !== undefined )
|
|
gl.uniform3f( this.addr, v.r, v.g, v.b );
|
|
else
|
|
gl.uniform3fv( this.addr, v );
|
|
|
|
}
|
|
|
|
function setValue4fv( gl, v ) {
|
|
|
|
if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
|
|
else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
|
|
|
|
}
|
|
|
|
// Single matrix (from flat array or MatrixN)
|
|
|
|
function setValue2fm( gl, v ) {
|
|
|
|
gl.uniformMatrix2fv( this.addr, false, v.elements || v );
|
|
|
|
}
|
|
|
|
function setValue3fm( gl, v ) {
|
|
|
|
if ( v.elements === undefined ) {
|
|
|
|
gl.uniformMatrix3fv( this.addr, false, v );
|
|
|
|
} else {
|
|
|
|
mat3array.set( v.elements );
|
|
gl.uniformMatrix3fv( this.addr, false, mat3array );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setValue4fm( gl, v ) {
|
|
|
|
if ( v.elements === undefined ) {
|
|
|
|
gl.uniformMatrix4fv( this.addr, false, v );
|
|
|
|
} else {
|
|
|
|
mat4array.set( v.elements );
|
|
gl.uniformMatrix4fv( this.addr, false, mat4array );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Single texture (2D / Cube)
|
|
|
|
function setValueT1( gl, v, renderer ) {
|
|
|
|
var unit = renderer.allocTextureUnit();
|
|
gl.uniform1i( this.addr, unit );
|
|
renderer.setTexture2D( v || emptyTexture, unit );
|
|
|
|
}
|
|
|
|
function setValueT6( gl, v, renderer ) {
|
|
|
|
var unit = renderer.allocTextureUnit();
|
|
gl.uniform1i( this.addr, unit );
|
|
renderer.setTextureCube( v || emptyCubeTexture, unit );
|
|
|
|
}
|
|
|
|
// Integer / Boolean vectors or arrays thereof (always flat arrays)
|
|
|
|
function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
|
|
function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
|
|
function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
|
|
|
|
// Helper to pick the right setter for the singular case
|
|
|
|
function getSingularSetter( type ) {
|
|
|
|
switch ( type ) {
|
|
|
|
case 0x1406: return setValue1f; // FLOAT
|
|
case 0x8b50: return setValue2fv; // _VEC2
|
|
case 0x8b51: return setValue3fv; // _VEC3
|
|
case 0x8b52: return setValue4fv; // _VEC4
|
|
|
|
case 0x8b5a: return setValue2fm; // _MAT2
|
|
case 0x8b5b: return setValue3fm; // _MAT3
|
|
case 0x8b5c: return setValue4fm; // _MAT4
|
|
|
|
case 0x8b5e: return setValueT1; // SAMPLER_2D
|
|
case 0x8b60: return setValueT6; // SAMPLER_CUBE
|
|
|
|
case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
|
|
case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
|
|
case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
|
|
case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Array of scalars
|
|
|
|
function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
|
|
function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
|
|
|
|
// Array of vectors (flat or from THREE classes)
|
|
|
|
function setValueV2a( gl, v ) {
|
|
|
|
gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );
|
|
|
|
}
|
|
|
|
function setValueV3a( gl, v ) {
|
|
|
|
gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );
|
|
|
|
}
|
|
|
|
function setValueV4a( gl, v ) {
|
|
|
|
gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );
|
|
|
|
}
|
|
|
|
// Array of matrices (flat or from THREE clases)
|
|
|
|
function setValueM2a( gl, v ) {
|
|
|
|
gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );
|
|
|
|
}
|
|
|
|
function setValueM3a( gl, v ) {
|
|
|
|
gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );
|
|
|
|
}
|
|
|
|
function setValueM4a( gl, v ) {
|
|
|
|
gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );
|
|
|
|
}
|
|
|
|
// Array of textures (2D / Cube)
|
|
|
|
function setValueT1a( gl, v, renderer ) {
|
|
|
|
var n = v.length,
|
|
units = allocTexUnits( renderer, n );
|
|
|
|
gl.uniform1iv( this.addr, units );
|
|
|
|
for ( var i = 0; i !== n; ++ i ) {
|
|
|
|
renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setValueT6a( gl, v, renderer ) {
|
|
|
|
var n = v.length,
|
|
units = allocTexUnits( renderer, n );
|
|
|
|
gl.uniform1iv( this.addr, units );
|
|
|
|
for ( var i = 0; i !== n; ++ i ) {
|
|
|
|
renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Helper to pick the right setter for a pure (bottom-level) array
|
|
|
|
function getPureArraySetter( type ) {
|
|
|
|
switch ( type ) {
|
|
|
|
case 0x1406: return setValue1fv; // FLOAT
|
|
case 0x8b50: return setValueV2a; // _VEC2
|
|
case 0x8b51: return setValueV3a; // _VEC3
|
|
case 0x8b52: return setValueV4a; // _VEC4
|
|
|
|
case 0x8b5a: return setValueM2a; // _MAT2
|
|
case 0x8b5b: return setValueM3a; // _MAT3
|
|
case 0x8b5c: return setValueM4a; // _MAT4
|
|
|
|
case 0x8b5e: return setValueT1a; // SAMPLER_2D
|
|
case 0x8b60: return setValueT6a; // SAMPLER_CUBE
|
|
|
|
case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
|
|
case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
|
|
case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
|
|
case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// --- Uniform Classes ---
|
|
|
|
function SingleUniform( id, activeInfo, addr ) {
|
|
|
|
this.id = id;
|
|
this.addr = addr;
|
|
this.setValue = getSingularSetter( activeInfo.type );
|
|
|
|
// this.path = activeInfo.name; // DEBUG
|
|
|
|
}
|
|
|
|
function PureArrayUniform( id, activeInfo, addr ) {
|
|
|
|
this.id = id;
|
|
this.addr = addr;
|
|
this.size = activeInfo.size;
|
|
this.setValue = getPureArraySetter( activeInfo.type );
|
|
|
|
// this.path = activeInfo.name; // DEBUG
|
|
|
|
}
|
|
|
|
function StructuredUniform( id ) {
|
|
|
|
this.id = id;
|
|
|
|
UniformContainer.call( this ); // mix-in
|
|
|
|
}
|
|
|
|
StructuredUniform.prototype.setValue = function ( gl, value ) {
|
|
|
|
// Note: Don't need an extra 'renderer' parameter, since samplers
|
|
// are not allowed in structured uniforms.
|
|
|
|
var seq = this.seq;
|
|
|
|
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
|
|
|
|
var u = seq[ i ];
|
|
u.setValue( gl, value[ u.id ] );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// --- Top-level ---
|
|
|
|
// Parser - builds up the property tree from the path strings
|
|
|
|
var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
|
|
|
|
// extracts
|
|
// - the identifier (member name or array index)
|
|
// - followed by an optional right bracket (found when array index)
|
|
// - followed by an optional left bracket or dot (type of subscript)
|
|
//
|
|
// Note: These portions can be read in a non-overlapping fashion and
|
|
// allow straightforward parsing of the hierarchy that WebGL encodes
|
|
// in the uniform names.
|
|
|
|
function addUniform( container, uniformObject ) {
|
|
|
|
container.seq.push( uniformObject );
|
|
container.map[ uniformObject.id ] = uniformObject;
|
|
|
|
}
|
|
|
|
function parseUniform( activeInfo, addr, container ) {
|
|
|
|
var path = activeInfo.name,
|
|
pathLength = path.length;
|
|
|
|
// reset RegExp object, because of the early exit of a previous run
|
|
RePathPart.lastIndex = 0;
|
|
|
|
for ( ; ; ) {
|
|
|
|
var match = RePathPart.exec( path ),
|
|
matchEnd = RePathPart.lastIndex,
|
|
|
|
id = match[ 1 ],
|
|
idIsIndex = match[ 2 ] === ']',
|
|
subscript = match[ 3 ];
|
|
|
|
if ( idIsIndex ) id = id | 0; // convert to integer
|
|
|
|
if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
|
|
|
|
// bare name or "pure" bottom-level array "[0]" suffix
|
|
|
|
addUniform( container, subscript === undefined ?
|
|
new SingleUniform( id, activeInfo, addr ) :
|
|
new PureArrayUniform( id, activeInfo, addr ) );
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// step into inner node / create it in case it doesn't exist
|
|
|
|
var map = container.map, next = map[ id ];
|
|
|
|
if ( next === undefined ) {
|
|
|
|
next = new StructuredUniform( id );
|
|
addUniform( container, next );
|
|
|
|
}
|
|
|
|
container = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Root Container
|
|
|
|
function WebGLUniforms( gl, program, renderer ) {
|
|
|
|
UniformContainer.call( this );
|
|
|
|
this.renderer = renderer;
|
|
|
|
var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
|
|
|
|
for ( var i = 0; i < n; ++ i ) {
|
|
|
|
var info = gl.getActiveUniform( program, i ),
|
|
path = info.name,
|
|
addr = gl.getUniformLocation( program, path );
|
|
|
|
parseUniform( info, addr, this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
WebGLUniforms.prototype.setValue = function ( gl, name, value ) {
|
|
|
|
var u = this.map[ name ];
|
|
|
|
if ( u !== undefined ) u.setValue( gl, value, this.renderer );
|
|
|
|
};
|
|
|
|
WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
|
|
|
|
var v = object[ name ];
|
|
|
|
if ( v !== undefined ) this.setValue( gl, name, v );
|
|
|
|
};
|
|
|
|
|
|
// Static interface
|
|
|
|
WebGLUniforms.upload = function ( gl, seq, values, renderer ) {
|
|
|
|
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
|
|
|
|
var u = seq[ i ],
|
|
v = values[ u.id ];
|
|
|
|
if ( v.needsUpdate !== false ) {
|
|
|
|
// note: always updating when .needsUpdate is undefined
|
|
u.setValue( gl, v.value, renderer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
WebGLUniforms.seqWithValue = function ( seq, values ) {
|
|
|
|
var r = [];
|
|
|
|
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
|
|
|
|
var u = seq[ i ];
|
|
if ( u.id in values ) r.push( u );
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
|
|
'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
|
|
'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
|
|
'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
|
|
'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
|
|
'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
|
|
'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
|
|
'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
|
|
'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
|
|
'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
|
|
'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
|
|
'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
|
|
'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
|
|
'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
|
|
'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
|
|
'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
|
|
'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
|
|
'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
|
|
'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
|
|
'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
|
|
'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
|
|
'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
|
|
'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
|
|
'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
|
|
|
|
function Color( r, g, b ) {
|
|
|
|
if ( g === undefined && b === undefined ) {
|
|
|
|
// r is THREE.Color, hex or string
|
|
return this.set( r );
|
|
|
|
}
|
|
|
|
return this.setRGB( r, g, b );
|
|
|
|
}
|
|
|
|
Object.assign( Color.prototype, {
|
|
|
|
isColor: true,
|
|
|
|
r: 1, g: 1, b: 1,
|
|
|
|
set: function ( value ) {
|
|
|
|
if ( value && value.isColor ) {
|
|
|
|
this.copy( value );
|
|
|
|
} else if ( typeof value === 'number' ) {
|
|
|
|
this.setHex( value );
|
|
|
|
} else if ( typeof value === 'string' ) {
|
|
|
|
this.setStyle( value );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setScalar: function ( scalar ) {
|
|
|
|
this.r = scalar;
|
|
this.g = scalar;
|
|
this.b = scalar;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setHex: function ( hex ) {
|
|
|
|
hex = Math.floor( hex );
|
|
|
|
this.r = ( hex >> 16 & 255 ) / 255;
|
|
this.g = ( hex >> 8 & 255 ) / 255;
|
|
this.b = ( hex & 255 ) / 255;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setRGB: function ( r, g, b ) {
|
|
|
|
this.r = r;
|
|
this.g = g;
|
|
this.b = b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setHSL: function () {
|
|
|
|
function hue2rgb( p, q, t ) {
|
|
|
|
if ( t < 0 ) t += 1;
|
|
if ( t > 1 ) t -= 1;
|
|
if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
|
|
if ( t < 1 / 2 ) return q;
|
|
if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
|
|
return p;
|
|
|
|
}
|
|
|
|
return function setHSL( h, s, l ) {
|
|
|
|
// h,s,l ranges are in 0.0 - 1.0
|
|
h = _Math.euclideanModulo( h, 1 );
|
|
s = _Math.clamp( s, 0, 1 );
|
|
l = _Math.clamp( l, 0, 1 );
|
|
|
|
if ( s === 0 ) {
|
|
|
|
this.r = this.g = this.b = l;
|
|
|
|
} else {
|
|
|
|
var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
|
|
var q = ( 2 * l ) - p;
|
|
|
|
this.r = hue2rgb( q, p, h + 1 / 3 );
|
|
this.g = hue2rgb( q, p, h );
|
|
this.b = hue2rgb( q, p, h - 1 / 3 );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
setStyle: function ( style ) {
|
|
|
|
function handleAlpha( string ) {
|
|
|
|
if ( string === undefined ) return;
|
|
|
|
if ( parseFloat( string ) < 1 ) {
|
|
|
|
console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
var m;
|
|
|
|
if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
|
|
|
|
// rgb / hsl
|
|
|
|
var color;
|
|
var name = m[ 1 ];
|
|
var components = m[ 2 ];
|
|
|
|
switch ( name ) {
|
|
|
|
case 'rgb':
|
|
case 'rgba':
|
|
|
|
if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
|
|
|
|
// rgb(255,0,0) rgba(255,0,0,0.5)
|
|
this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
|
|
this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
|
|
this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
|
|
|
|
handleAlpha( color[ 5 ] );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
|
|
|
|
// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
|
|
this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
|
|
this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
|
|
this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
|
|
|
|
handleAlpha( color[ 5 ] );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'hsl':
|
|
case 'hsla':
|
|
|
|
if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
|
|
|
|
// hsl(120,50%,50%) hsla(120,50%,50%,0.5)
|
|
var h = parseFloat( color[ 1 ] ) / 360;
|
|
var s = parseInt( color[ 2 ], 10 ) / 100;
|
|
var l = parseInt( color[ 3 ], 10 ) / 100;
|
|
|
|
handleAlpha( color[ 5 ] );
|
|
|
|
return this.setHSL( h, s, l );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
|
|
|
|
// hex color
|
|
|
|
var hex = m[ 1 ];
|
|
var size = hex.length;
|
|
|
|
if ( size === 3 ) {
|
|
|
|
// #ff0
|
|
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
|
|
this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
|
|
this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
|
|
|
|
return this;
|
|
|
|
} else if ( size === 6 ) {
|
|
|
|
// #ff0000
|
|
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
|
|
this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
|
|
this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( style && style.length > 0 ) {
|
|
|
|
// color keywords
|
|
var hex = ColorKeywords[ style ];
|
|
|
|
if ( hex !== undefined ) {
|
|
|
|
// red
|
|
this.setHex( hex );
|
|
|
|
} else {
|
|
|
|
// unknown color
|
|
console.warn( 'THREE.Color: Unknown color ' + style );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.r, this.g, this.b );
|
|
|
|
},
|
|
|
|
copy: function ( color ) {
|
|
|
|
this.r = color.r;
|
|
this.g = color.g;
|
|
this.b = color.b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyGammaToLinear: function ( color, gammaFactor ) {
|
|
|
|
if ( gammaFactor === undefined ) gammaFactor = 2.0;
|
|
|
|
this.r = Math.pow( color.r, gammaFactor );
|
|
this.g = Math.pow( color.g, gammaFactor );
|
|
this.b = Math.pow( color.b, gammaFactor );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyLinearToGamma: function ( color, gammaFactor ) {
|
|
|
|
if ( gammaFactor === undefined ) gammaFactor = 2.0;
|
|
|
|
var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
|
|
|
|
this.r = Math.pow( color.r, safeInverse );
|
|
this.g = Math.pow( color.g, safeInverse );
|
|
this.b = Math.pow( color.b, safeInverse );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
convertGammaToLinear: function () {
|
|
|
|
var r = this.r, g = this.g, b = this.b;
|
|
|
|
this.r = r * r;
|
|
this.g = g * g;
|
|
this.b = b * b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
convertLinearToGamma: function () {
|
|
|
|
this.r = Math.sqrt( this.r );
|
|
this.g = Math.sqrt( this.g );
|
|
this.b = Math.sqrt( this.b );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getHex: function () {
|
|
|
|
return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
|
|
|
|
},
|
|
|
|
getHexString: function () {
|
|
|
|
return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
|
|
|
|
},
|
|
|
|
getHSL: function ( optionalTarget ) {
|
|
|
|
// h,s,l ranges are in 0.0 - 1.0
|
|
|
|
var hsl = optionalTarget || { h: 0, s: 0, l: 0 };
|
|
|
|
var r = this.r, g = this.g, b = this.b;
|
|
|
|
var max = Math.max( r, g, b );
|
|
var min = Math.min( r, g, b );
|
|
|
|
var hue, saturation;
|
|
var lightness = ( min + max ) / 2.0;
|
|
|
|
if ( min === max ) {
|
|
|
|
hue = 0;
|
|
saturation = 0;
|
|
|
|
} else {
|
|
|
|
var delta = max - min;
|
|
|
|
saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
|
|
|
|
switch ( max ) {
|
|
|
|
case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
|
|
case g: hue = ( b - r ) / delta + 2; break;
|
|
case b: hue = ( r - g ) / delta + 4; break;
|
|
|
|
}
|
|
|
|
hue /= 6;
|
|
|
|
}
|
|
|
|
hsl.h = hue;
|
|
hsl.s = saturation;
|
|
hsl.l = lightness;
|
|
|
|
return hsl;
|
|
|
|
},
|
|
|
|
getStyle: function () {
|
|
|
|
return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
|
|
|
|
},
|
|
|
|
offsetHSL: function ( h, s, l ) {
|
|
|
|
var hsl = this.getHSL();
|
|
|
|
hsl.h += h; hsl.s += s; hsl.l += l;
|
|
|
|
this.setHSL( hsl.h, hsl.s, hsl.l );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
add: function ( color ) {
|
|
|
|
this.r += color.r;
|
|
this.g += color.g;
|
|
this.b += color.b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addColors: function ( color1, color2 ) {
|
|
|
|
this.r = color1.r + color2.r;
|
|
this.g = color1.g + color2.g;
|
|
this.b = color1.b + color2.b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addScalar: function ( s ) {
|
|
|
|
this.r += s;
|
|
this.g += s;
|
|
this.b += s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
sub: function( color ) {
|
|
|
|
this.r = Math.max( 0, this.r - color.r );
|
|
this.g = Math.max( 0, this.g - color.g );
|
|
this.b = Math.max( 0, this.b - color.b );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiply: function ( color ) {
|
|
|
|
this.r *= color.r;
|
|
this.g *= color.g;
|
|
this.b *= color.b;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( s ) {
|
|
|
|
this.r *= s;
|
|
this.g *= s;
|
|
this.b *= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
lerp: function ( color, alpha ) {
|
|
|
|
this.r += ( color.r - this.r ) * alpha;
|
|
this.g += ( color.g - this.g ) * alpha;
|
|
this.b += ( color.b - this.b ) * alpha;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( c ) {
|
|
|
|
return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.r = array[ offset ];
|
|
this.g = array[ offset + 1 ];
|
|
this.b = array[ offset + 2 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this.r;
|
|
array[ offset + 1 ] = this.g;
|
|
array[ offset + 2 ] = this.b;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
toJSON: function () {
|
|
|
|
return this.getHex();
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* Uniforms library for shared webgl shaders
|
|
*/
|
|
|
|
var UniformsLib = {
|
|
|
|
common: {
|
|
|
|
diffuse: { value: new Color( 0xeeeeee ) },
|
|
opacity: { value: 1.0 },
|
|
|
|
map: { value: null },
|
|
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
|
|
|
|
specularMap: { value: null },
|
|
alphaMap: { value: null },
|
|
|
|
envMap: { value: null },
|
|
flipEnvMap: { value: - 1 },
|
|
reflectivity: { value: 1.0 },
|
|
refractionRatio: { value: 0.98 }
|
|
|
|
},
|
|
|
|
aomap: {
|
|
|
|
aoMap: { value: null },
|
|
aoMapIntensity: { value: 1 }
|
|
|
|
},
|
|
|
|
lightmap: {
|
|
|
|
lightMap: { value: null },
|
|
lightMapIntensity: { value: 1 }
|
|
|
|
},
|
|
|
|
emissivemap: {
|
|
|
|
emissiveMap: { value: null }
|
|
|
|
},
|
|
|
|
bumpmap: {
|
|
|
|
bumpMap: { value: null },
|
|
bumpScale: { value: 1 }
|
|
|
|
},
|
|
|
|
normalmap: {
|
|
|
|
normalMap: { value: null },
|
|
normalScale: { value: new Vector2( 1, 1 ) }
|
|
|
|
},
|
|
|
|
displacementmap: {
|
|
|
|
displacementMap: { value: null },
|
|
displacementScale: { value: 1 },
|
|
displacementBias: { value: 0 }
|
|
|
|
},
|
|
|
|
roughnessmap: {
|
|
|
|
roughnessMap: { value: null }
|
|
|
|
},
|
|
|
|
metalnessmap: {
|
|
|
|
metalnessMap: { value: null }
|
|
|
|
},
|
|
|
|
gradientmap: {
|
|
|
|
gradientMap: { value: null }
|
|
|
|
},
|
|
|
|
fog: {
|
|
|
|
fogDensity: { value: 0.00025 },
|
|
fogNear: { value: 1 },
|
|
fogFar: { value: 2000 },
|
|
fogColor: { value: new Color( 0xffffff ) }
|
|
|
|
},
|
|
|
|
lights: {
|
|
|
|
ambientLightColor: { value: [] },
|
|
|
|
directionalLights: { value: [], properties: {
|
|
direction: {},
|
|
color: {},
|
|
|
|
shadow: {},
|
|
shadowBias: {},
|
|
shadowRadius: {},
|
|
shadowMapSize: {}
|
|
} },
|
|
|
|
directionalShadowMap: { value: [] },
|
|
directionalShadowMatrix: { value: [] },
|
|
|
|
spotLights: { value: [], properties: {
|
|
color: {},
|
|
position: {},
|
|
direction: {},
|
|
distance: {},
|
|
coneCos: {},
|
|
penumbraCos: {},
|
|
decay: {},
|
|
|
|
shadow: {},
|
|
shadowBias: {},
|
|
shadowRadius: {},
|
|
shadowMapSize: {}
|
|
} },
|
|
|
|
spotShadowMap: { value: [] },
|
|
spotShadowMatrix: { value: [] },
|
|
|
|
pointLights: { value: [], properties: {
|
|
color: {},
|
|
position: {},
|
|
decay: {},
|
|
distance: {},
|
|
|
|
shadow: {},
|
|
shadowBias: {},
|
|
shadowRadius: {},
|
|
shadowMapSize: {}
|
|
} },
|
|
|
|
pointShadowMap: { value: [] },
|
|
pointShadowMatrix: { value: [] },
|
|
|
|
hemisphereLights: { value: [], properties: {
|
|
direction: {},
|
|
skyColor: {},
|
|
groundColor: {}
|
|
} },
|
|
|
|
// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
|
|
rectAreaLights: { value: [], properties: {
|
|
color: {},
|
|
position: {},
|
|
width: {},
|
|
height: {}
|
|
} }
|
|
|
|
},
|
|
|
|
points: {
|
|
|
|
diffuse: { value: new Color( 0xeeeeee ) },
|
|
opacity: { value: 1.0 },
|
|
size: { value: 1.0 },
|
|
scale: { value: 1.0 },
|
|
map: { value: null },
|
|
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Uniform Utilities
|
|
*/
|
|
|
|
var UniformsUtils = {
|
|
|
|
merge: function ( uniforms ) {
|
|
|
|
var merged = {};
|
|
|
|
for ( var u = 0; u < uniforms.length; u ++ ) {
|
|
|
|
var tmp = this.clone( uniforms[ u ] );
|
|
|
|
for ( var p in tmp ) {
|
|
|
|
merged[ p ] = tmp[ p ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return merged;
|
|
|
|
},
|
|
|
|
clone: function ( uniforms_src ) {
|
|
|
|
var uniforms_dst = {};
|
|
|
|
for ( var u in uniforms_src ) {
|
|
|
|
uniforms_dst[ u ] = {};
|
|
|
|
for ( var p in uniforms_src[ u ] ) {
|
|
|
|
var parameter_src = uniforms_src[ u ][ p ];
|
|
|
|
if ( parameter_src && ( parameter_src.isColor ||
|
|
parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
|
|
parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
|
|
parameter_src.isTexture ) ) {
|
|
|
|
uniforms_dst[ u ][ p ] = parameter_src.clone();
|
|
|
|
} else if ( Array.isArray( parameter_src ) ) {
|
|
|
|
uniforms_dst[ u ][ p ] = parameter_src.slice();
|
|
|
|
} else {
|
|
|
|
uniforms_dst[ u ][ p ] = parameter_src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return uniforms_dst;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n";
|
|
|
|
var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n";
|
|
|
|
var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n";
|
|
|
|
var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n";
|
|
|
|
var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
|
|
|
|
var begin_vertex = "\nvec3 transformed = vec3( position );\n";
|
|
|
|
var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n";
|
|
|
|
var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat theta = acos( dot( N, V ) );\n\tvec2 uv = vec2(\n\t\tsqrt( saturate( roughness ) ),\n\t\tsaturate( theta / ( 0.5 * PI ) ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.86267 + (0.49788 + 0.01436 * y ) * y;\n\tfloat b = 3.45068 + (4.18814 + y) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = (x > 0.0) ? v : 0.5 * inversesqrt( 1.0 - x * x ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tvec3 result = vec3( LTC_ClippedSphereFormFactor( vectorFormFactor ) );\n\treturn result;\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n";
|
|
|
|
var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n";
|
|
|
|
var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n";
|
|
|
|
var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n";
|
|
|
|
var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n";
|
|
|
|
var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n";
|
|
|
|
var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
|
|
|
|
var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n";
|
|
|
|
var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
|
|
|
|
var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";
|
|
|
|
var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transpose( const in mat3 v ) {\n\tmat3 tmp;\n\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\n\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\n\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\n\treturn tmp;\n}\n";
|
|
|
|
var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n";
|
|
|
|
var defaultnormal_vertex = "#ifdef FLIP_SIDED\n\tobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;\n";
|
|
|
|
var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n";
|
|
|
|
var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n";
|
|
|
|
var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n";
|
|
|
|
var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n";
|
|
|
|
var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n";
|
|
|
|
var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n";
|
|
|
|
var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n";
|
|
|
|
var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n";
|
|
|
|
var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n";
|
|
|
|
var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n";
|
|
|
|
var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif";
|
|
|
|
var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n";
|
|
|
|
var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n";
|
|
|
|
var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n";
|
|
|
|
var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n";
|
|
|
|
var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n";
|
|
|
|
var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
|
|
|
|
var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n";
|
|
|
|
var lights_pars = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltcMat;\tuniform sampler2D ltcMag;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n";
|
|
|
|
var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n";
|
|
|
|
var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tfloat norm = texture2D( ltcMag, uv ).a;\n\t\tvec4 t = texture2D( ltcMat, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( 1, 0, t.y ),\n\t\t\tvec3( 0, t.z, 0 ),\n\t\t\tvec3( t.w, 0, t.x )\n\t\t);\n\t\treflectedLight.directSpecular += lightColor * material.specularColor * norm * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n";
|
|
|
|
var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n";
|
|
|
|
var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tfloat norm = texture2D( ltcMag, uv ).a;\n\t\tvec4 t = texture2D( ltcMat, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( 1, 0, t.y ),\n\t\t\tvec3( 0, t.z, 0 ),\n\t\t\tvec3( t.w, 0, t.x )\n\t\t);\n\t\treflectedLight.directSpecular += lightColor * material.specularColor * norm * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n";
|
|
|
|
var lights_template = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n";
|
|
|
|
var logdepthbuf_fragment = "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif";
|
|
|
|
var logdepthbuf_pars_fragment = "#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n";
|
|
|
|
var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif";
|
|
|
|
var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n";
|
|
|
|
var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n";
|
|
|
|
var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n";
|
|
|
|
var map_particle_fragment = "#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n";
|
|
|
|
var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n";
|
|
|
|
var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n";
|
|
|
|
var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
|
|
|
|
var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n";
|
|
|
|
var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
|
|
|
|
var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n";
|
|
|
|
var normal_flip = "#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n";
|
|
|
|
var normal_fragment = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n";
|
|
|
|
var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
|
|
|
|
var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
|
|
|
|
var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
|
|
|
|
var project_vertex = "#ifdef USE_SKINNING\n\tvec4 mvPosition = modelViewMatrix * skinned;\n#else\n\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;\n";
|
|
|
|
var dithering_fragment = "#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n";
|
|
|
|
var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n";
|
|
|
|
var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n";
|
|
|
|
var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
|
|
|
|
var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn 1.0;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n";
|
|
|
|
var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n";
|
|
|
|
var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n";
|
|
|
|
var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n";
|
|
|
|
var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
|
|
|
|
var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n";
|
|
|
|
var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n#endif\n";
|
|
|
|
var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n";
|
|
|
|
var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
|
|
|
|
var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
|
|
|
|
var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n";
|
|
|
|
var tonemapping_pars_fragment = "#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n";
|
|
|
|
var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif";
|
|
|
|
var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n#endif\n";
|
|
|
|
var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif";
|
|
|
|
var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
|
|
|
|
var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif";
|
|
|
|
var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif";
|
|
|
|
var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\t#ifdef USE_SKINNING\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\t#else\n\t\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\t#endif\n#endif\n";
|
|
|
|
var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n";
|
|
|
|
var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
|
|
|
|
var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n";
|
|
|
|
var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n";
|
|
|
|
var distanceRGBA_frag = "uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include <common>\n#include <packing>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n";
|
|
|
|
var distanceRGBA_vert = "varying vec4 vWorldPosition;\n#include <common>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition;\n}\n";
|
|
|
|
var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n";
|
|
|
|
var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
|
|
|
|
var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
|
|
|
|
var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
|
|
|
|
var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
|
|
|
|
var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
|
|
|
|
var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
|
|
|
|
var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n";
|
|
|
|
var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n";
|
|
|
|
var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
|
|
|
|
var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
|
|
|
|
var shadow_frag = "uniform float opacity;\n#include <common>\n#include <packing>\n#include <bsdfs>\n#include <lights_pars>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n";
|
|
|
|
var shadow_vert = "#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n}\n";
|
|
|
|
var ShaderChunk = {
|
|
alphamap_fragment: alphamap_fragment,
|
|
alphamap_pars_fragment: alphamap_pars_fragment,
|
|
alphatest_fragment: alphatest_fragment,
|
|
aomap_fragment: aomap_fragment,
|
|
aomap_pars_fragment: aomap_pars_fragment,
|
|
begin_vertex: begin_vertex,
|
|
beginnormal_vertex: beginnormal_vertex,
|
|
bsdfs: bsdfs,
|
|
bumpmap_pars_fragment: bumpmap_pars_fragment,
|
|
clipping_planes_fragment: clipping_planes_fragment,
|
|
clipping_planes_pars_fragment: clipping_planes_pars_fragment,
|
|
clipping_planes_pars_vertex: clipping_planes_pars_vertex,
|
|
clipping_planes_vertex: clipping_planes_vertex,
|
|
color_fragment: color_fragment,
|
|
color_pars_fragment: color_pars_fragment,
|
|
color_pars_vertex: color_pars_vertex,
|
|
color_vertex: color_vertex,
|
|
common: common,
|
|
cube_uv_reflection_fragment: cube_uv_reflection_fragment,
|
|
defaultnormal_vertex: defaultnormal_vertex,
|
|
displacementmap_pars_vertex: displacementmap_pars_vertex,
|
|
displacementmap_vertex: displacementmap_vertex,
|
|
emissivemap_fragment: emissivemap_fragment,
|
|
emissivemap_pars_fragment: emissivemap_pars_fragment,
|
|
encodings_fragment: encodings_fragment,
|
|
encodings_pars_fragment: encodings_pars_fragment,
|
|
envmap_fragment: envmap_fragment,
|
|
envmap_pars_fragment: envmap_pars_fragment,
|
|
envmap_pars_vertex: envmap_pars_vertex,
|
|
envmap_vertex: envmap_vertex,
|
|
fog_vertex: fog_vertex,
|
|
fog_pars_vertex: fog_pars_vertex,
|
|
fog_fragment: fog_fragment,
|
|
fog_pars_fragment: fog_pars_fragment,
|
|
gradientmap_pars_fragment: gradientmap_pars_fragment,
|
|
lightmap_fragment: lightmap_fragment,
|
|
lightmap_pars_fragment: lightmap_pars_fragment,
|
|
lights_lambert_vertex: lights_lambert_vertex,
|
|
lights_pars: lights_pars,
|
|
lights_phong_fragment: lights_phong_fragment,
|
|
lights_phong_pars_fragment: lights_phong_pars_fragment,
|
|
lights_physical_fragment: lights_physical_fragment,
|
|
lights_physical_pars_fragment: lights_physical_pars_fragment,
|
|
lights_template: lights_template,
|
|
logdepthbuf_fragment: logdepthbuf_fragment,
|
|
logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
|
|
logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
|
|
logdepthbuf_vertex: logdepthbuf_vertex,
|
|
map_fragment: map_fragment,
|
|
map_pars_fragment: map_pars_fragment,
|
|
map_particle_fragment: map_particle_fragment,
|
|
map_particle_pars_fragment: map_particle_pars_fragment,
|
|
metalnessmap_fragment: metalnessmap_fragment,
|
|
metalnessmap_pars_fragment: metalnessmap_pars_fragment,
|
|
morphnormal_vertex: morphnormal_vertex,
|
|
morphtarget_pars_vertex: morphtarget_pars_vertex,
|
|
morphtarget_vertex: morphtarget_vertex,
|
|
normal_flip: normal_flip,
|
|
normal_fragment: normal_fragment,
|
|
normalmap_pars_fragment: normalmap_pars_fragment,
|
|
packing: packing,
|
|
premultiplied_alpha_fragment: premultiplied_alpha_fragment,
|
|
project_vertex: project_vertex,
|
|
dithering_fragment: dithering_fragment,
|
|
dithering_pars_fragment: dithering_pars_fragment,
|
|
roughnessmap_fragment: roughnessmap_fragment,
|
|
roughnessmap_pars_fragment: roughnessmap_pars_fragment,
|
|
shadowmap_pars_fragment: shadowmap_pars_fragment,
|
|
shadowmap_pars_vertex: shadowmap_pars_vertex,
|
|
shadowmap_vertex: shadowmap_vertex,
|
|
shadowmask_pars_fragment: shadowmask_pars_fragment,
|
|
skinbase_vertex: skinbase_vertex,
|
|
skinning_pars_vertex: skinning_pars_vertex,
|
|
skinning_vertex: skinning_vertex,
|
|
skinnormal_vertex: skinnormal_vertex,
|
|
specularmap_fragment: specularmap_fragment,
|
|
specularmap_pars_fragment: specularmap_pars_fragment,
|
|
tonemapping_fragment: tonemapping_fragment,
|
|
tonemapping_pars_fragment: tonemapping_pars_fragment,
|
|
uv_pars_fragment: uv_pars_fragment,
|
|
uv_pars_vertex: uv_pars_vertex,
|
|
uv_vertex: uv_vertex,
|
|
uv2_pars_fragment: uv2_pars_fragment,
|
|
uv2_pars_vertex: uv2_pars_vertex,
|
|
uv2_vertex: uv2_vertex,
|
|
worldpos_vertex: worldpos_vertex,
|
|
|
|
cube_frag: cube_frag,
|
|
cube_vert: cube_vert,
|
|
depth_frag: depth_frag,
|
|
depth_vert: depth_vert,
|
|
distanceRGBA_frag: distanceRGBA_frag,
|
|
distanceRGBA_vert: distanceRGBA_vert,
|
|
equirect_frag: equirect_frag,
|
|
equirect_vert: equirect_vert,
|
|
linedashed_frag: linedashed_frag,
|
|
linedashed_vert: linedashed_vert,
|
|
meshbasic_frag: meshbasic_frag,
|
|
meshbasic_vert: meshbasic_vert,
|
|
meshlambert_frag: meshlambert_frag,
|
|
meshlambert_vert: meshlambert_vert,
|
|
meshphong_frag: meshphong_frag,
|
|
meshphong_vert: meshphong_vert,
|
|
meshphysical_frag: meshphysical_frag,
|
|
meshphysical_vert: meshphysical_vert,
|
|
normal_frag: normal_frag,
|
|
normal_vert: normal_vert,
|
|
points_frag: points_frag,
|
|
points_vert: points_vert,
|
|
shadow_frag: shadow_frag,
|
|
shadow_vert: shadow_vert
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
*/
|
|
|
|
var ShaderLib = {
|
|
|
|
basic: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.aomap,
|
|
UniformsLib.lightmap,
|
|
UniformsLib.fog
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.meshbasic_vert,
|
|
fragmentShader: ShaderChunk.meshbasic_frag
|
|
|
|
},
|
|
|
|
lambert: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.aomap,
|
|
UniformsLib.lightmap,
|
|
UniformsLib.emissivemap,
|
|
UniformsLib.fog,
|
|
UniformsLib.lights,
|
|
{
|
|
emissive: { value: new Color( 0x000000 ) }
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.meshlambert_vert,
|
|
fragmentShader: ShaderChunk.meshlambert_frag
|
|
|
|
},
|
|
|
|
phong: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.aomap,
|
|
UniformsLib.lightmap,
|
|
UniformsLib.emissivemap,
|
|
UniformsLib.bumpmap,
|
|
UniformsLib.normalmap,
|
|
UniformsLib.displacementmap,
|
|
UniformsLib.gradientmap,
|
|
UniformsLib.fog,
|
|
UniformsLib.lights,
|
|
{
|
|
emissive: { value: new Color( 0x000000 ) },
|
|
specular: { value: new Color( 0x111111 ) },
|
|
shininess: { value: 30 }
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.meshphong_vert,
|
|
fragmentShader: ShaderChunk.meshphong_frag
|
|
|
|
},
|
|
|
|
standard: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.aomap,
|
|
UniformsLib.lightmap,
|
|
UniformsLib.emissivemap,
|
|
UniformsLib.bumpmap,
|
|
UniformsLib.normalmap,
|
|
UniformsLib.displacementmap,
|
|
UniformsLib.roughnessmap,
|
|
UniformsLib.metalnessmap,
|
|
UniformsLib.fog,
|
|
UniformsLib.lights,
|
|
{
|
|
emissive: { value: new Color( 0x000000 ) },
|
|
roughness: { value: 0.5 },
|
|
metalness: { value: 0.5 },
|
|
envMapIntensity: { value: 1 } // temporary
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.meshphysical_vert,
|
|
fragmentShader: ShaderChunk.meshphysical_frag
|
|
|
|
},
|
|
|
|
points: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.points,
|
|
UniformsLib.fog
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.points_vert,
|
|
fragmentShader: ShaderChunk.points_frag
|
|
|
|
},
|
|
|
|
dashed: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.fog,
|
|
{
|
|
scale: { value: 1 },
|
|
dashSize: { value: 1 },
|
|
totalSize: { value: 2 }
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.linedashed_vert,
|
|
fragmentShader: ShaderChunk.linedashed_frag
|
|
|
|
},
|
|
|
|
depth: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.displacementmap
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.depth_vert,
|
|
fragmentShader: ShaderChunk.depth_frag
|
|
|
|
},
|
|
|
|
normal: {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.common,
|
|
UniformsLib.bumpmap,
|
|
UniformsLib.normalmap,
|
|
UniformsLib.displacementmap,
|
|
{
|
|
opacity: { value: 1.0 }
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.normal_vert,
|
|
fragmentShader: ShaderChunk.normal_frag
|
|
|
|
},
|
|
|
|
/* -------------------------------------------------------------------------
|
|
// Cube map shader
|
|
------------------------------------------------------------------------- */
|
|
|
|
cube: {
|
|
|
|
uniforms: {
|
|
tCube: { value: null },
|
|
tFlip: { value: - 1 },
|
|
opacity: { value: 1.0 }
|
|
},
|
|
|
|
vertexShader: ShaderChunk.cube_vert,
|
|
fragmentShader: ShaderChunk.cube_frag
|
|
|
|
},
|
|
|
|
/* -------------------------------------------------------------------------
|
|
// Cube map shader
|
|
------------------------------------------------------------------------- */
|
|
|
|
equirect: {
|
|
|
|
uniforms: {
|
|
tEquirect: { value: null },
|
|
tFlip: { value: - 1 }
|
|
},
|
|
|
|
vertexShader: ShaderChunk.equirect_vert,
|
|
fragmentShader: ShaderChunk.equirect_frag
|
|
|
|
},
|
|
|
|
distanceRGBA: {
|
|
|
|
uniforms: {
|
|
lightPos: { value: new Vector3() }
|
|
},
|
|
|
|
vertexShader: ShaderChunk.distanceRGBA_vert,
|
|
fragmentShader: ShaderChunk.distanceRGBA_frag
|
|
|
|
}
|
|
|
|
};
|
|
|
|
ShaderLib.physical = {
|
|
|
|
uniforms: UniformsUtils.merge( [
|
|
ShaderLib.standard.uniforms,
|
|
{
|
|
clearCoat: { value: 0 },
|
|
clearCoatRoughness: { value: 0 }
|
|
}
|
|
] ),
|
|
|
|
vertexShader: ShaderChunk.meshphysical_vert,
|
|
fragmentShader: ShaderChunk.meshphysical_frag
|
|
|
|
};
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Box2( min, max ) {
|
|
|
|
this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
|
|
this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
|
|
|
|
}
|
|
|
|
Object.assign( Box2.prototype, {
|
|
|
|
set: function ( min, max ) {
|
|
|
|
this.min.copy( min );
|
|
this.max.copy( max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromPoints: function ( points ) {
|
|
|
|
this.makeEmpty();
|
|
|
|
for ( var i = 0, il = points.length; i < il; i ++ ) {
|
|
|
|
this.expandByPoint( points[ i ] );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromCenterAndSize: function () {
|
|
|
|
var v1 = new Vector2();
|
|
|
|
return function setFromCenterAndSize( center, size ) {
|
|
|
|
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
|
|
this.min.copy( center ).sub( halfSize );
|
|
this.max.copy( center ).add( halfSize );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( box ) {
|
|
|
|
this.min.copy( box.min );
|
|
this.max.copy( box.max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeEmpty: function () {
|
|
|
|
this.min.x = this.min.y = + Infinity;
|
|
this.max.x = this.max.y = - Infinity;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
isEmpty: function () {
|
|
|
|
// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
|
|
|
|
return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
|
|
|
|
},
|
|
|
|
getCenter: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector2();
|
|
return this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
|
|
|
|
},
|
|
|
|
getSize: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector2();
|
|
return this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );
|
|
|
|
},
|
|
|
|
expandByPoint: function ( point ) {
|
|
|
|
this.min.min( point );
|
|
this.max.max( point );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
expandByVector: function ( vector ) {
|
|
|
|
this.min.sub( vector );
|
|
this.max.add( vector );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
expandByScalar: function ( scalar ) {
|
|
|
|
this.min.addScalar( - scalar );
|
|
this.max.addScalar( scalar );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
containsPoint: function ( point ) {
|
|
|
|
return point.x < this.min.x || point.x > this.max.x ||
|
|
point.y < this.min.y || point.y > this.max.y ? false : true;
|
|
|
|
},
|
|
|
|
containsBox: function ( box ) {
|
|
|
|
return this.min.x <= box.min.x && box.max.x <= this.max.x &&
|
|
this.min.y <= box.min.y && box.max.y <= this.max.y;
|
|
|
|
},
|
|
|
|
getParameter: function ( point, optionalTarget ) {
|
|
|
|
// This can potentially have a divide by zero if the box
|
|
// has a size dimension of 0.
|
|
|
|
var result = optionalTarget || new Vector2();
|
|
|
|
return result.set(
|
|
( point.x - this.min.x ) / ( this.max.x - this.min.x ),
|
|
( point.y - this.min.y ) / ( this.max.y - this.min.y )
|
|
);
|
|
|
|
},
|
|
|
|
intersectsBox: function ( box ) {
|
|
|
|
// using 4 splitting planes to rule out intersections
|
|
|
|
return box.max.x < this.min.x || box.min.x > this.max.x ||
|
|
box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
|
|
|
|
},
|
|
|
|
clampPoint: function ( point, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector2();
|
|
return result.copy( point ).clamp( this.min, this.max );
|
|
|
|
},
|
|
|
|
distanceToPoint: function () {
|
|
|
|
var v1 = new Vector2();
|
|
|
|
return function distanceToPoint( point ) {
|
|
|
|
var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
|
|
return clampedPoint.sub( point ).length();
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersect: function ( box ) {
|
|
|
|
this.min.max( box.min );
|
|
this.max.min( box.max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
union: function ( box ) {
|
|
|
|
this.min.min( box.min );
|
|
this.max.max( box.max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
translate: function ( offset ) {
|
|
|
|
this.min.add( offset );
|
|
this.max.add( offset );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( box ) {
|
|
|
|
return box.min.equals( this.min ) && box.max.equals( this.max );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function LensFlarePlugin( renderer, flares ) {
|
|
|
|
var gl = renderer.context;
|
|
var state = renderer.state;
|
|
|
|
var vertexBuffer, elementBuffer;
|
|
var shader, program, attributes, uniforms;
|
|
|
|
var tempTexture, occlusionTexture;
|
|
|
|
function init() {
|
|
|
|
var vertices = new Float32Array( [
|
|
- 1, - 1, 0, 0,
|
|
1, - 1, 1, 0,
|
|
1, 1, 1, 1,
|
|
- 1, 1, 0, 1
|
|
] );
|
|
|
|
var faces = new Uint16Array( [
|
|
0, 1, 2,
|
|
0, 2, 3
|
|
] );
|
|
|
|
// buffers
|
|
|
|
vertexBuffer = gl.createBuffer();
|
|
elementBuffer = gl.createBuffer();
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
|
|
gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
|
|
|
|
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
|
|
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
|
|
|
|
// textures
|
|
|
|
tempTexture = gl.createTexture();
|
|
occlusionTexture = gl.createTexture();
|
|
|
|
state.bindTexture( gl.TEXTURE_2D, tempTexture );
|
|
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
|
|
|
|
state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
|
|
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
|
|
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
|
|
|
|
shader = {
|
|
|
|
vertexShader: [
|
|
|
|
"uniform lowp int renderType;",
|
|
|
|
"uniform vec3 screenPosition;",
|
|
"uniform vec2 scale;",
|
|
"uniform float rotation;",
|
|
|
|
"uniform sampler2D occlusionMap;",
|
|
|
|
"attribute vec2 position;",
|
|
"attribute vec2 uv;",
|
|
|
|
"varying vec2 vUV;",
|
|
"varying float vVisibility;",
|
|
|
|
"void main() {",
|
|
|
|
"vUV = uv;",
|
|
|
|
"vec2 pos = position;",
|
|
|
|
"if ( renderType == 2 ) {",
|
|
|
|
"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );",
|
|
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
|
|
|
|
"vVisibility = visibility.r / 9.0;",
|
|
"vVisibility *= 1.0 - visibility.g / 9.0;",
|
|
"vVisibility *= visibility.b / 9.0;",
|
|
"vVisibility *= 1.0 - visibility.a / 9.0;",
|
|
|
|
"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
|
|
"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
|
|
|
|
"}",
|
|
|
|
"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
|
|
|
|
"}"
|
|
|
|
].join( "\n" ),
|
|
|
|
fragmentShader: [
|
|
|
|
"uniform lowp int renderType;",
|
|
|
|
"uniform sampler2D map;",
|
|
"uniform float opacity;",
|
|
"uniform vec3 color;",
|
|
|
|
"varying vec2 vUV;",
|
|
"varying float vVisibility;",
|
|
|
|
"void main() {",
|
|
|
|
// pink square
|
|
|
|
"if ( renderType == 0 ) {",
|
|
|
|
"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
|
|
|
|
// restore
|
|
|
|
"} else if ( renderType == 1 ) {",
|
|
|
|
"gl_FragColor = texture2D( map, vUV );",
|
|
|
|
// flare
|
|
|
|
"} else {",
|
|
|
|
"vec4 texture = texture2D( map, vUV );",
|
|
"texture.a *= opacity * vVisibility;",
|
|
"gl_FragColor = texture;",
|
|
"gl_FragColor.rgb *= color;",
|
|
|
|
"}",
|
|
|
|
"}"
|
|
|
|
].join( "\n" )
|
|
|
|
};
|
|
|
|
program = createProgram( shader );
|
|
|
|
attributes = {
|
|
vertex: gl.getAttribLocation ( program, "position" ),
|
|
uv: gl.getAttribLocation ( program, "uv" )
|
|
};
|
|
|
|
uniforms = {
|
|
renderType: gl.getUniformLocation( program, "renderType" ),
|
|
map: gl.getUniformLocation( program, "map" ),
|
|
occlusionMap: gl.getUniformLocation( program, "occlusionMap" ),
|
|
opacity: gl.getUniformLocation( program, "opacity" ),
|
|
color: gl.getUniformLocation( program, "color" ),
|
|
scale: gl.getUniformLocation( program, "scale" ),
|
|
rotation: gl.getUniformLocation( program, "rotation" ),
|
|
screenPosition: gl.getUniformLocation( program, "screenPosition" )
|
|
};
|
|
|
|
}
|
|
|
|
/*
|
|
* Render lens flares
|
|
* Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
|
|
* reads these back and calculates occlusion.
|
|
*/
|
|
|
|
this.render = function ( scene, camera, viewport ) {
|
|
|
|
if ( flares.length === 0 ) return;
|
|
|
|
var tempPosition = new Vector3();
|
|
|
|
var invAspect = viewport.w / viewport.z,
|
|
halfViewportWidth = viewport.z * 0.5,
|
|
halfViewportHeight = viewport.w * 0.5;
|
|
|
|
var size = 16 / viewport.w,
|
|
scale = new Vector2( size * invAspect, size );
|
|
|
|
var screenPosition = new Vector3( 1, 1, 0 ),
|
|
screenPositionPixels = new Vector2( 1, 1 );
|
|
|
|
var validArea = new Box2();
|
|
|
|
validArea.min.set( viewport.x, viewport.y );
|
|
validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );
|
|
|
|
if ( program === undefined ) {
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
gl.useProgram( program );
|
|
|
|
state.initAttributes();
|
|
state.enableAttribute( attributes.vertex );
|
|
state.enableAttribute( attributes.uv );
|
|
state.disableUnusedAttributes();
|
|
|
|
// loop through all lens flares to update their occlusion and positions
|
|
// setup gl and common used attribs/uniforms
|
|
|
|
gl.uniform1i( uniforms.occlusionMap, 0 );
|
|
gl.uniform1i( uniforms.map, 1 );
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
|
|
gl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );
|
|
gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
|
|
|
|
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
|
|
|
|
state.disable( gl.CULL_FACE );
|
|
state.buffers.depth.setMask( false );
|
|
|
|
for ( var i = 0, l = flares.length; i < l; i ++ ) {
|
|
|
|
size = 16 / viewport.w;
|
|
scale.set( size * invAspect, size );
|
|
|
|
// calc object screen position
|
|
|
|
var flare = flares[ i ];
|
|
|
|
tempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );
|
|
|
|
tempPosition.applyMatrix4( camera.matrixWorldInverse );
|
|
tempPosition.applyMatrix4( camera.projectionMatrix );
|
|
|
|
// setup arrays for gl programs
|
|
|
|
screenPosition.copy( tempPosition );
|
|
|
|
// horizontal and vertical coordinate of the lower left corner of the pixels to copy
|
|
|
|
screenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;
|
|
screenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;
|
|
|
|
// screen cull
|
|
|
|
if ( validArea.containsPoint( screenPositionPixels ) === true ) {
|
|
|
|
// save current RGB to temp texture
|
|
|
|
state.activeTexture( gl.TEXTURE0 );
|
|
state.bindTexture( gl.TEXTURE_2D, null );
|
|
state.activeTexture( gl.TEXTURE1 );
|
|
state.bindTexture( gl.TEXTURE_2D, tempTexture );
|
|
gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
|
|
|
|
|
|
// render pink quad
|
|
|
|
gl.uniform1i( uniforms.renderType, 0 );
|
|
gl.uniform2f( uniforms.scale, scale.x, scale.y );
|
|
gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
|
|
|
|
state.disable( gl.BLEND );
|
|
state.enable( gl.DEPTH_TEST );
|
|
|
|
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
|
|
|
|
|
|
// copy result to occlusionMap
|
|
|
|
state.activeTexture( gl.TEXTURE0 );
|
|
state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
|
|
gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
|
|
|
|
|
|
// restore graphics
|
|
|
|
gl.uniform1i( uniforms.renderType, 1 );
|
|
state.disable( gl.DEPTH_TEST );
|
|
|
|
state.activeTexture( gl.TEXTURE1 );
|
|
state.bindTexture( gl.TEXTURE_2D, tempTexture );
|
|
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
|
|
|
|
|
|
// update object positions
|
|
|
|
flare.positionScreen.copy( screenPosition );
|
|
|
|
if ( flare.customUpdateCallback ) {
|
|
|
|
flare.customUpdateCallback( flare );
|
|
|
|
} else {
|
|
|
|
flare.updateLensFlares();
|
|
|
|
}
|
|
|
|
// render flares
|
|
|
|
gl.uniform1i( uniforms.renderType, 2 );
|
|
state.enable( gl.BLEND );
|
|
|
|
for ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
|
|
|
|
var sprite = flare.lensFlares[ j ];
|
|
|
|
if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
|
|
|
|
screenPosition.x = sprite.x;
|
|
screenPosition.y = sprite.y;
|
|
screenPosition.z = sprite.z;
|
|
|
|
size = sprite.size * sprite.scale / viewport.w;
|
|
|
|
scale.x = size * invAspect;
|
|
scale.y = size;
|
|
|
|
gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
|
|
gl.uniform2f( uniforms.scale, scale.x, scale.y );
|
|
gl.uniform1f( uniforms.rotation, sprite.rotation );
|
|
|
|
gl.uniform1f( uniforms.opacity, sprite.opacity );
|
|
gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
|
|
|
|
state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
|
|
renderer.setTexture2D( sprite.texture, 1 );
|
|
|
|
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// restore gl
|
|
|
|
state.enable( gl.CULL_FACE );
|
|
state.enable( gl.DEPTH_TEST );
|
|
state.buffers.depth.setMask( true );
|
|
|
|
renderer.resetGLState();
|
|
|
|
};
|
|
|
|
function createProgram( shader ) {
|
|
|
|
var program = gl.createProgram();
|
|
|
|
var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
|
|
var vertexShader = gl.createShader( gl.VERTEX_SHADER );
|
|
|
|
var prefix = "precision " + renderer.getPrecision() + " float;\n";
|
|
|
|
gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
|
|
gl.shaderSource( vertexShader, prefix + shader.vertexShader );
|
|
|
|
gl.compileShader( fragmentShader );
|
|
gl.compileShader( vertexShader );
|
|
|
|
gl.attachShader( program, fragmentShader );
|
|
gl.attachShader( program, vertexShader );
|
|
|
|
gl.linkProgram( program );
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function SpritePlugin( renderer, sprites ) {
|
|
|
|
var gl = renderer.context;
|
|
var state = renderer.state;
|
|
|
|
var vertexBuffer, elementBuffer;
|
|
var program, attributes, uniforms;
|
|
|
|
var texture;
|
|
|
|
// decompose matrixWorld
|
|
|
|
var spritePosition = new Vector3();
|
|
var spriteRotation = new Quaternion();
|
|
var spriteScale = new Vector3();
|
|
|
|
function init() {
|
|
|
|
var vertices = new Float32Array( [
|
|
- 0.5, - 0.5, 0, 0,
|
|
0.5, - 0.5, 1, 0,
|
|
0.5, 0.5, 1, 1,
|
|
- 0.5, 0.5, 0, 1
|
|
] );
|
|
|
|
var faces = new Uint16Array( [
|
|
0, 1, 2,
|
|
0, 2, 3
|
|
] );
|
|
|
|
vertexBuffer = gl.createBuffer();
|
|
elementBuffer = gl.createBuffer();
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
|
|
gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
|
|
|
|
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
|
|
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
|
|
|
|
program = createProgram();
|
|
|
|
attributes = {
|
|
position: gl.getAttribLocation ( program, 'position' ),
|
|
uv: gl.getAttribLocation ( program, 'uv' )
|
|
};
|
|
|
|
uniforms = {
|
|
uvOffset: gl.getUniformLocation( program, 'uvOffset' ),
|
|
uvScale: gl.getUniformLocation( program, 'uvScale' ),
|
|
|
|
rotation: gl.getUniformLocation( program, 'rotation' ),
|
|
scale: gl.getUniformLocation( program, 'scale' ),
|
|
|
|
color: gl.getUniformLocation( program, 'color' ),
|
|
map: gl.getUniformLocation( program, 'map' ),
|
|
opacity: gl.getUniformLocation( program, 'opacity' ),
|
|
|
|
modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ),
|
|
projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ),
|
|
|
|
fogType: gl.getUniformLocation( program, 'fogType' ),
|
|
fogDensity: gl.getUniformLocation( program, 'fogDensity' ),
|
|
fogNear: gl.getUniformLocation( program, 'fogNear' ),
|
|
fogFar: gl.getUniformLocation( program, 'fogFar' ),
|
|
fogColor: gl.getUniformLocation( program, 'fogColor' ),
|
|
|
|
alphaTest: gl.getUniformLocation( program, 'alphaTest' )
|
|
};
|
|
|
|
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
|
|
canvas.width = 8;
|
|
canvas.height = 8;
|
|
|
|
var context = canvas.getContext( '2d' );
|
|
context.fillStyle = 'white';
|
|
context.fillRect( 0, 0, 8, 8 );
|
|
|
|
texture = new Texture( canvas );
|
|
texture.needsUpdate = true;
|
|
|
|
}
|
|
|
|
this.render = function ( scene, camera ) {
|
|
|
|
if ( sprites.length === 0 ) return;
|
|
|
|
// setup gl
|
|
|
|
if ( program === undefined ) {
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
gl.useProgram( program );
|
|
|
|
state.initAttributes();
|
|
state.enableAttribute( attributes.position );
|
|
state.enableAttribute( attributes.uv );
|
|
state.disableUnusedAttributes();
|
|
|
|
state.disable( gl.CULL_FACE );
|
|
state.enable( gl.BLEND );
|
|
|
|
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
|
|
gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );
|
|
gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
|
|
|
|
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
|
|
|
|
gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
|
|
|
|
state.activeTexture( gl.TEXTURE0 );
|
|
gl.uniform1i( uniforms.map, 0 );
|
|
|
|
var oldFogType = 0;
|
|
var sceneFogType = 0;
|
|
var fog = scene.fog;
|
|
|
|
if ( fog ) {
|
|
|
|
gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
|
|
|
|
if ( fog.isFog ) {
|
|
|
|
gl.uniform1f( uniforms.fogNear, fog.near );
|
|
gl.uniform1f( uniforms.fogFar, fog.far );
|
|
|
|
gl.uniform1i( uniforms.fogType, 1 );
|
|
oldFogType = 1;
|
|
sceneFogType = 1;
|
|
|
|
} else if ( fog.isFogExp2 ) {
|
|
|
|
gl.uniform1f( uniforms.fogDensity, fog.density );
|
|
|
|
gl.uniform1i( uniforms.fogType, 2 );
|
|
oldFogType = 2;
|
|
sceneFogType = 2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gl.uniform1i( uniforms.fogType, 0 );
|
|
oldFogType = 0;
|
|
sceneFogType = 0;
|
|
|
|
}
|
|
|
|
|
|
// update positions and sort
|
|
|
|
for ( var i = 0, l = sprites.length; i < l; i ++ ) {
|
|
|
|
var sprite = sprites[ i ];
|
|
|
|
sprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );
|
|
sprite.z = - sprite.modelViewMatrix.elements[ 14 ];
|
|
|
|
}
|
|
|
|
sprites.sort( painterSortStable );
|
|
|
|
// render all sprites
|
|
|
|
var scale = [];
|
|
|
|
for ( var i = 0, l = sprites.length; i < l; i ++ ) {
|
|
|
|
var sprite = sprites[ i ];
|
|
var material = sprite.material;
|
|
|
|
if ( material.visible === false ) continue;
|
|
|
|
gl.uniform1f( uniforms.alphaTest, material.alphaTest );
|
|
gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );
|
|
|
|
sprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );
|
|
|
|
scale[ 0 ] = spriteScale.x;
|
|
scale[ 1 ] = spriteScale.y;
|
|
|
|
var fogType = 0;
|
|
|
|
if ( scene.fog && material.fog ) {
|
|
|
|
fogType = sceneFogType;
|
|
|
|
}
|
|
|
|
if ( oldFogType !== fogType ) {
|
|
|
|
gl.uniform1i( uniforms.fogType, fogType );
|
|
oldFogType = fogType;
|
|
|
|
}
|
|
|
|
if ( material.map !== null ) {
|
|
|
|
gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );
|
|
gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );
|
|
|
|
} else {
|
|
|
|
gl.uniform2f( uniforms.uvOffset, 0, 0 );
|
|
gl.uniform2f( uniforms.uvScale, 1, 1 );
|
|
|
|
}
|
|
|
|
gl.uniform1f( uniforms.opacity, material.opacity );
|
|
gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );
|
|
|
|
gl.uniform1f( uniforms.rotation, material.rotation );
|
|
gl.uniform2fv( uniforms.scale, scale );
|
|
|
|
state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
|
|
state.buffers.depth.setTest( material.depthTest );
|
|
state.buffers.depth.setMask( material.depthWrite );
|
|
|
|
if ( material.map ) {
|
|
|
|
renderer.setTexture2D( material.map, 0 );
|
|
|
|
} else {
|
|
|
|
renderer.setTexture2D( texture, 0 );
|
|
|
|
}
|
|
|
|
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
|
|
|
|
}
|
|
|
|
// restore gl
|
|
|
|
state.enable( gl.CULL_FACE );
|
|
|
|
renderer.resetGLState();
|
|
|
|
};
|
|
|
|
function createProgram() {
|
|
|
|
var program = gl.createProgram();
|
|
|
|
var vertexShader = gl.createShader( gl.VERTEX_SHADER );
|
|
var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
|
|
|
|
gl.shaderSource( vertexShader, [
|
|
|
|
'precision ' + renderer.getPrecision() + ' float;',
|
|
|
|
'uniform mat4 modelViewMatrix;',
|
|
'uniform mat4 projectionMatrix;',
|
|
'uniform float rotation;',
|
|
'uniform vec2 scale;',
|
|
'uniform vec2 uvOffset;',
|
|
'uniform vec2 uvScale;',
|
|
|
|
'attribute vec2 position;',
|
|
'attribute vec2 uv;',
|
|
|
|
'varying vec2 vUV;',
|
|
|
|
'void main() {',
|
|
|
|
'vUV = uvOffset + uv * uvScale;',
|
|
|
|
'vec2 alignedPosition = position * scale;',
|
|
|
|
'vec2 rotatedPosition;',
|
|
'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',
|
|
'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',
|
|
|
|
'vec4 finalPosition;',
|
|
|
|
'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',
|
|
'finalPosition.xy += rotatedPosition;',
|
|
'finalPosition = projectionMatrix * finalPosition;',
|
|
|
|
'gl_Position = finalPosition;',
|
|
|
|
'}'
|
|
|
|
].join( '\n' ) );
|
|
|
|
gl.shaderSource( fragmentShader, [
|
|
|
|
'precision ' + renderer.getPrecision() + ' float;',
|
|
|
|
'uniform vec3 color;',
|
|
'uniform sampler2D map;',
|
|
'uniform float opacity;',
|
|
|
|
'uniform int fogType;',
|
|
'uniform vec3 fogColor;',
|
|
'uniform float fogDensity;',
|
|
'uniform float fogNear;',
|
|
'uniform float fogFar;',
|
|
'uniform float alphaTest;',
|
|
|
|
'varying vec2 vUV;',
|
|
|
|
'void main() {',
|
|
|
|
'vec4 texture = texture2D( map, vUV );',
|
|
|
|
'if ( texture.a < alphaTest ) discard;',
|
|
|
|
'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',
|
|
|
|
'if ( fogType > 0 ) {',
|
|
|
|
'float depth = gl_FragCoord.z / gl_FragCoord.w;',
|
|
'float fogFactor = 0.0;',
|
|
|
|
'if ( fogType == 1 ) {',
|
|
|
|
'fogFactor = smoothstep( fogNear, fogFar, depth );',
|
|
|
|
'} else {',
|
|
|
|
'const float LOG2 = 1.442695;',
|
|
'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',
|
|
'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',
|
|
|
|
'}',
|
|
|
|
'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',
|
|
|
|
'}',
|
|
|
|
'}'
|
|
|
|
].join( '\n' ) );
|
|
|
|
gl.compileShader( vertexShader );
|
|
gl.compileShader( fragmentShader );
|
|
|
|
gl.attachShader( program, vertexShader );
|
|
gl.attachShader( program, fragmentShader );
|
|
|
|
gl.linkProgram( program );
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
function painterSortStable( a, b ) {
|
|
|
|
if ( a.renderOrder !== b.renderOrder ) {
|
|
|
|
return a.renderOrder - b.renderOrder;
|
|
|
|
} else if ( a.z !== b.z ) {
|
|
|
|
return b.z - a.z;
|
|
|
|
} else {
|
|
|
|
return b.id - a.id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
var materialId = 0;
|
|
|
|
function Material() {
|
|
|
|
Object.defineProperty( this, 'id', { value: materialId ++ } );
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.name = '';
|
|
this.type = 'Material';
|
|
|
|
this.fog = true;
|
|
this.lights = true;
|
|
|
|
this.blending = NormalBlending;
|
|
this.side = FrontSide;
|
|
this.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading
|
|
this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors
|
|
|
|
this.opacity = 1;
|
|
this.transparent = false;
|
|
|
|
this.blendSrc = SrcAlphaFactor;
|
|
this.blendDst = OneMinusSrcAlphaFactor;
|
|
this.blendEquation = AddEquation;
|
|
this.blendSrcAlpha = null;
|
|
this.blendDstAlpha = null;
|
|
this.blendEquationAlpha = null;
|
|
|
|
this.depthFunc = LessEqualDepth;
|
|
this.depthTest = true;
|
|
this.depthWrite = true;
|
|
|
|
this.clippingPlanes = null;
|
|
this.clipIntersection = false;
|
|
this.clipShadows = false;
|
|
|
|
this.colorWrite = true;
|
|
|
|
this.precision = null; // override the renderer's default precision for this material
|
|
|
|
this.polygonOffset = false;
|
|
this.polygonOffsetFactor = 0;
|
|
this.polygonOffsetUnits = 0;
|
|
|
|
this.dithering = false;
|
|
|
|
this.alphaTest = 0;
|
|
this.premultipliedAlpha = false;
|
|
|
|
this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer
|
|
|
|
this.visible = true;
|
|
|
|
this.needsUpdate = true;
|
|
|
|
}
|
|
|
|
Object.assign( Material.prototype, EventDispatcher.prototype, {
|
|
|
|
isMaterial: true,
|
|
|
|
setValues: function ( values ) {
|
|
|
|
if ( values === undefined ) return;
|
|
|
|
for ( var key in values ) {
|
|
|
|
var newValue = values[ key ];
|
|
|
|
if ( newValue === undefined ) {
|
|
|
|
console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
|
|
continue;
|
|
|
|
}
|
|
|
|
var currentValue = this[ key ];
|
|
|
|
if ( currentValue === undefined ) {
|
|
|
|
console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( currentValue && currentValue.isColor ) {
|
|
|
|
currentValue.set( newValue );
|
|
|
|
} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
|
|
|
|
currentValue.copy( newValue );
|
|
|
|
} else if ( key === 'overdraw' ) {
|
|
|
|
// ensure overdraw is backwards-compatible with legacy boolean type
|
|
this[ key ] = Number( newValue );
|
|
|
|
} else {
|
|
|
|
this[ key ] = newValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var isRoot = meta === undefined;
|
|
|
|
if ( isRoot ) {
|
|
|
|
meta = {
|
|
textures: {},
|
|
images: {}
|
|
};
|
|
|
|
}
|
|
|
|
var data = {
|
|
metadata: {
|
|
version: 4.5,
|
|
type: 'Material',
|
|
generator: 'Material.toJSON'
|
|
}
|
|
};
|
|
|
|
// standard Material serialization
|
|
data.uuid = this.uuid;
|
|
data.type = this.type;
|
|
|
|
if ( this.name !== '' ) data.name = this.name;
|
|
|
|
if ( this.color && this.color.isColor ) data.color = this.color.getHex();
|
|
|
|
if ( this.roughness !== undefined ) data.roughness = this.roughness;
|
|
if ( this.metalness !== undefined ) data.metalness = this.metalness;
|
|
|
|
if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
|
|
if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
|
|
if ( this.shininess !== undefined ) data.shininess = this.shininess;
|
|
if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;
|
|
if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;
|
|
|
|
if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
|
|
if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
|
|
if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
|
|
if ( this.bumpMap && this.bumpMap.isTexture ) {
|
|
|
|
data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
|
|
data.bumpScale = this.bumpScale;
|
|
|
|
}
|
|
if ( this.normalMap && this.normalMap.isTexture ) {
|
|
|
|
data.normalMap = this.normalMap.toJSON( meta ).uuid;
|
|
data.normalScale = this.normalScale.toArray();
|
|
|
|
}
|
|
if ( this.displacementMap && this.displacementMap.isTexture ) {
|
|
|
|
data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
|
|
data.displacementScale = this.displacementScale;
|
|
data.displacementBias = this.displacementBias;
|
|
|
|
}
|
|
if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
|
|
if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
|
|
|
|
if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
|
|
if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
|
|
|
|
if ( this.envMap && this.envMap.isTexture ) {
|
|
|
|
data.envMap = this.envMap.toJSON( meta ).uuid;
|
|
data.reflectivity = this.reflectivity; // Scale behind envMap
|
|
|
|
}
|
|
|
|
if ( this.gradientMap && this.gradientMap.isTexture ) {
|
|
|
|
data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
|
|
|
|
}
|
|
|
|
if ( this.size !== undefined ) data.size = this.size;
|
|
if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
|
|
|
|
if ( this.blending !== NormalBlending ) data.blending = this.blending;
|
|
if ( this.shading !== SmoothShading ) data.shading = this.shading;
|
|
if ( this.side !== FrontSide ) data.side = this.side;
|
|
if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;
|
|
|
|
if ( this.opacity < 1 ) data.opacity = this.opacity;
|
|
if ( this.transparent === true ) data.transparent = this.transparent;
|
|
|
|
data.depthFunc = this.depthFunc;
|
|
data.depthTest = this.depthTest;
|
|
data.depthWrite = this.depthWrite;
|
|
|
|
if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
|
|
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
|
|
if ( this.wireframe === true ) data.wireframe = this.wireframe;
|
|
if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
|
|
if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
|
|
if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
|
|
|
|
data.skinning = this.skinning;
|
|
data.morphTargets = this.morphTargets;
|
|
|
|
data.dithering = this.dithering;
|
|
|
|
// TODO: Copied from Object3D.toJSON
|
|
|
|
function extractFromCache( cache ) {
|
|
|
|
var values = [];
|
|
|
|
for ( var key in cache ) {
|
|
|
|
var data = cache[ key ];
|
|
delete data.metadata;
|
|
values.push( data );
|
|
|
|
}
|
|
|
|
return values;
|
|
|
|
}
|
|
|
|
if ( isRoot ) {
|
|
|
|
var textures = extractFromCache( meta.textures );
|
|
var images = extractFromCache( meta.images );
|
|
|
|
if ( textures.length > 0 ) data.textures = textures;
|
|
if ( images.length > 0 ) data.images = images;
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.name = source.name;
|
|
|
|
this.fog = source.fog;
|
|
this.lights = source.lights;
|
|
|
|
this.blending = source.blending;
|
|
this.side = source.side;
|
|
this.shading = source.shading;
|
|
this.vertexColors = source.vertexColors;
|
|
|
|
this.opacity = source.opacity;
|
|
this.transparent = source.transparent;
|
|
|
|
this.blendSrc = source.blendSrc;
|
|
this.blendDst = source.blendDst;
|
|
this.blendEquation = source.blendEquation;
|
|
this.blendSrcAlpha = source.blendSrcAlpha;
|
|
this.blendDstAlpha = source.blendDstAlpha;
|
|
this.blendEquationAlpha = source.blendEquationAlpha;
|
|
|
|
this.depthFunc = source.depthFunc;
|
|
this.depthTest = source.depthTest;
|
|
this.depthWrite = source.depthWrite;
|
|
|
|
this.colorWrite = source.colorWrite;
|
|
|
|
this.precision = source.precision;
|
|
|
|
this.polygonOffset = source.polygonOffset;
|
|
this.polygonOffsetFactor = source.polygonOffsetFactor;
|
|
this.polygonOffsetUnits = source.polygonOffsetUnits;
|
|
|
|
this.dithering = source.dithering;
|
|
|
|
this.alphaTest = source.alphaTest;
|
|
|
|
this.premultipliedAlpha = source.premultipliedAlpha;
|
|
|
|
this.overdraw = source.overdraw;
|
|
|
|
this.visible = source.visible;
|
|
this.clipShadows = source.clipShadows;
|
|
this.clipIntersection = source.clipIntersection;
|
|
|
|
var srcPlanes = source.clippingPlanes,
|
|
dstPlanes = null;
|
|
|
|
if ( srcPlanes !== null ) {
|
|
|
|
var n = srcPlanes.length;
|
|
dstPlanes = new Array( n );
|
|
|
|
for ( var i = 0; i !== n; ++ i )
|
|
dstPlanes[ i ] = srcPlanes[ i ].clone();
|
|
|
|
}
|
|
|
|
this.clippingPlanes = dstPlanes;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dispose: function () {
|
|
|
|
this.dispatchEvent( { type: 'dispose' } );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* defines: { "label" : "value" },
|
|
* uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
|
|
*
|
|
* fragmentShader: <string>,
|
|
* vertexShader: <string>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>,
|
|
*
|
|
* lights: <bool>,
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>,
|
|
* morphNormals: <bool>
|
|
* }
|
|
*/
|
|
|
|
function ShaderMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'ShaderMaterial';
|
|
|
|
this.defines = {};
|
|
this.uniforms = {};
|
|
|
|
this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
|
|
this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
|
|
|
|
this.linewidth = 1;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
|
|
this.fog = false; // set to use scene fog
|
|
this.lights = false; // set to use scene lights
|
|
this.clipping = false; // set to use user-defined clipping planes
|
|
|
|
this.skinning = false; // set to use skinning attribute streams
|
|
this.morphTargets = false; // set to use morph targets
|
|
this.morphNormals = false; // set to use morph normals
|
|
|
|
this.extensions = {
|
|
derivatives: false, // set to use derivatives
|
|
fragDepth: false, // set to use fragment depth values
|
|
drawBuffers: false, // set to use draw buffers
|
|
shaderTextureLOD: false // set to use shader texture LOD
|
|
};
|
|
|
|
// When rendered geometry doesn't include these attributes but the material does,
|
|
// use these default values in WebGL. This avoids errors when buffer data is missing.
|
|
this.defaultAttributeValues = {
|
|
'color': [ 1, 1, 1 ],
|
|
'uv': [ 0, 0 ],
|
|
'uv2': [ 0, 0 ]
|
|
};
|
|
|
|
this.index0AttributeName = undefined;
|
|
|
|
if ( parameters !== undefined ) {
|
|
|
|
if ( parameters.attributes !== undefined ) {
|
|
|
|
console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
|
|
|
|
}
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ShaderMaterial.prototype = Object.create( Material.prototype );
|
|
ShaderMaterial.prototype.constructor = ShaderMaterial;
|
|
|
|
ShaderMaterial.prototype.isShaderMaterial = true;
|
|
|
|
ShaderMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.fragmentShader = source.fragmentShader;
|
|
this.vertexShader = source.vertexShader;
|
|
|
|
this.uniforms = UniformsUtils.clone( source.uniforms );
|
|
|
|
this.defines = source.defines;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
|
|
this.lights = source.lights;
|
|
this.clipping = source.clipping;
|
|
|
|
this.skinning = source.skinning;
|
|
|
|
this.morphTargets = source.morphTargets;
|
|
this.morphNormals = source.morphNormals;
|
|
|
|
this.extensions = source.extensions;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
ShaderMaterial.prototype.toJSON = function ( meta ) {
|
|
|
|
var data = Material.prototype.toJSON.call( this, meta );
|
|
|
|
data.uniforms = this.uniforms;
|
|
data.vertexShader = this.vertexShader;
|
|
data.fragmentShader = this.fragmentShader;
|
|
|
|
return data;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author bhouston / https://clara.io
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*
|
|
* parameters = {
|
|
*
|
|
* opacity: <float>,
|
|
*
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* alphaMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* displacementMap: new THREE.Texture( <Image> ),
|
|
* displacementScale: <float>,
|
|
* displacementBias: <float>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>
|
|
* }
|
|
*/
|
|
|
|
function MeshDepthMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'MeshDepthMaterial';
|
|
|
|
this.depthPacking = BasicDepthPacking;
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
|
|
this.map = null;
|
|
|
|
this.alphaMap = null;
|
|
|
|
this.displacementMap = null;
|
|
this.displacementScale = 1;
|
|
this.displacementBias = 0;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
|
|
this.fog = false;
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshDepthMaterial.prototype = Object.create( Material.prototype );
|
|
MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
|
|
|
|
MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
|
|
|
|
MeshDepthMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.depthPacking = source.depthPacking;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
|
|
this.map = source.map;
|
|
|
|
this.alphaMap = source.alphaMap;
|
|
|
|
this.displacementMap = source.displacementMap;
|
|
this.displacementScale = source.displacementScale;
|
|
this.displacementBias = source.displacementBias;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function Box3( min, max ) {
|
|
|
|
this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
|
|
this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
|
|
|
|
}
|
|
|
|
Object.assign( Box3.prototype, {
|
|
|
|
isBox3: true,
|
|
|
|
set: function ( min, max ) {
|
|
|
|
this.min.copy( min );
|
|
this.max.copy( max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromArray: function ( array ) {
|
|
|
|
var minX = + Infinity;
|
|
var minY = + Infinity;
|
|
var minZ = + Infinity;
|
|
|
|
var maxX = - Infinity;
|
|
var maxY = - Infinity;
|
|
var maxZ = - Infinity;
|
|
|
|
for ( var i = 0, l = array.length; i < l; i += 3 ) {
|
|
|
|
var x = array[ i ];
|
|
var y = array[ i + 1 ];
|
|
var z = array[ i + 2 ];
|
|
|
|
if ( x < minX ) minX = x;
|
|
if ( y < minY ) minY = y;
|
|
if ( z < minZ ) minZ = z;
|
|
|
|
if ( x > maxX ) maxX = x;
|
|
if ( y > maxY ) maxY = y;
|
|
if ( z > maxZ ) maxZ = z;
|
|
|
|
}
|
|
|
|
this.min.set( minX, minY, minZ );
|
|
this.max.set( maxX, maxY, maxZ );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromBufferAttribute: function ( attribute ) {
|
|
|
|
var minX = + Infinity;
|
|
var minY = + Infinity;
|
|
var minZ = + Infinity;
|
|
|
|
var maxX = - Infinity;
|
|
var maxY = - Infinity;
|
|
var maxZ = - Infinity;
|
|
|
|
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
|
|
|
|
var x = attribute.getX( i );
|
|
var y = attribute.getY( i );
|
|
var z = attribute.getZ( i );
|
|
|
|
if ( x < minX ) minX = x;
|
|
if ( y < minY ) minY = y;
|
|
if ( z < minZ ) minZ = z;
|
|
|
|
if ( x > maxX ) maxX = x;
|
|
if ( y > maxY ) maxY = y;
|
|
if ( z > maxZ ) maxZ = z;
|
|
|
|
}
|
|
|
|
this.min.set( minX, minY, minZ );
|
|
this.max.set( maxX, maxY, maxZ );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromPoints: function ( points ) {
|
|
|
|
this.makeEmpty();
|
|
|
|
for ( var i = 0, il = points.length; i < il; i ++ ) {
|
|
|
|
this.expandByPoint( points[ i ] );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromCenterAndSize: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function setFromCenterAndSize( center, size ) {
|
|
|
|
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
|
|
|
|
this.min.copy( center ).sub( halfSize );
|
|
this.max.copy( center ).add( halfSize );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
setFromObject: function ( object ) {
|
|
|
|
this.makeEmpty();
|
|
|
|
return this.expandByObject( object );
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( box ) {
|
|
|
|
this.min.copy( box.min );
|
|
this.max.copy( box.max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
makeEmpty: function () {
|
|
|
|
this.min.x = this.min.y = this.min.z = + Infinity;
|
|
this.max.x = this.max.y = this.max.z = - Infinity;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
isEmpty: function () {
|
|
|
|
// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
|
|
|
|
return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
|
|
|
|
},
|
|
|
|
getCenter: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
|
|
|
|
},
|
|
|
|
getSize: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );
|
|
|
|
},
|
|
|
|
expandByPoint: function ( point ) {
|
|
|
|
this.min.min( point );
|
|
this.max.max( point );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
expandByVector: function ( vector ) {
|
|
|
|
this.min.sub( vector );
|
|
this.max.add( vector );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
expandByScalar: function ( scalar ) {
|
|
|
|
this.min.addScalar( - scalar );
|
|
this.max.addScalar( scalar );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
expandByObject: function () {
|
|
|
|
// Computes the world-axis-aligned bounding box of an object (including its children),
|
|
// accounting for both the object's, and children's, world transforms
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function expandByObject( object ) {
|
|
|
|
var scope = this;
|
|
|
|
object.updateMatrixWorld( true );
|
|
|
|
object.traverse( function ( node ) {
|
|
|
|
var i, l;
|
|
|
|
var geometry = node.geometry;
|
|
|
|
if ( geometry !== undefined ) {
|
|
|
|
if ( geometry.isGeometry ) {
|
|
|
|
var vertices = geometry.vertices;
|
|
|
|
for ( i = 0, l = vertices.length; i < l; i ++ ) {
|
|
|
|
v1.copy( vertices[ i ] );
|
|
v1.applyMatrix4( node.matrixWorld );
|
|
|
|
scope.expandByPoint( v1 );
|
|
|
|
}
|
|
|
|
} else if ( geometry.isBufferGeometry ) {
|
|
|
|
var attribute = geometry.attributes.position;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
for ( i = 0, l = attribute.count; i < l; i ++ ) {
|
|
|
|
v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );
|
|
|
|
scope.expandByPoint( v1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
containsPoint: function ( point ) {
|
|
|
|
return point.x < this.min.x || point.x > this.max.x ||
|
|
point.y < this.min.y || point.y > this.max.y ||
|
|
point.z < this.min.z || point.z > this.max.z ? false : true;
|
|
|
|
},
|
|
|
|
containsBox: function ( box ) {
|
|
|
|
return this.min.x <= box.min.x && box.max.x <= this.max.x &&
|
|
this.min.y <= box.min.y && box.max.y <= this.max.y &&
|
|
this.min.z <= box.min.z && box.max.z <= this.max.z;
|
|
|
|
},
|
|
|
|
getParameter: function ( point, optionalTarget ) {
|
|
|
|
// This can potentially have a divide by zero if the box
|
|
// has a size dimension of 0.
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
return result.set(
|
|
( point.x - this.min.x ) / ( this.max.x - this.min.x ),
|
|
( point.y - this.min.y ) / ( this.max.y - this.min.y ),
|
|
( point.z - this.min.z ) / ( this.max.z - this.min.z )
|
|
);
|
|
|
|
},
|
|
|
|
intersectsBox: function ( box ) {
|
|
|
|
// using 6 splitting planes to rule out intersections.
|
|
return box.max.x < this.min.x || box.min.x > this.max.x ||
|
|
box.max.y < this.min.y || box.min.y > this.max.y ||
|
|
box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
|
|
|
|
},
|
|
|
|
intersectsSphere: ( function () {
|
|
|
|
var closestPoint = new Vector3();
|
|
|
|
return function intersectsSphere( sphere ) {
|
|
|
|
// Find the point on the AABB closest to the sphere center.
|
|
this.clampPoint( sphere.center, closestPoint );
|
|
|
|
// If that point is inside the sphere, the AABB and sphere intersect.
|
|
return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
|
|
|
|
};
|
|
|
|
} )(),
|
|
|
|
intersectsPlane: function ( plane ) {
|
|
|
|
// We compute the minimum and maximum dot product values. If those values
|
|
// are on the same side (back or front) of the plane, then there is no intersection.
|
|
|
|
var min, max;
|
|
|
|
if ( plane.normal.x > 0 ) {
|
|
|
|
min = plane.normal.x * this.min.x;
|
|
max = plane.normal.x * this.max.x;
|
|
|
|
} else {
|
|
|
|
min = plane.normal.x * this.max.x;
|
|
max = plane.normal.x * this.min.x;
|
|
|
|
}
|
|
|
|
if ( plane.normal.y > 0 ) {
|
|
|
|
min += plane.normal.y * this.min.y;
|
|
max += plane.normal.y * this.max.y;
|
|
|
|
} else {
|
|
|
|
min += plane.normal.y * this.max.y;
|
|
max += plane.normal.y * this.min.y;
|
|
|
|
}
|
|
|
|
if ( plane.normal.z > 0 ) {
|
|
|
|
min += plane.normal.z * this.min.z;
|
|
max += plane.normal.z * this.max.z;
|
|
|
|
} else {
|
|
|
|
min += plane.normal.z * this.max.z;
|
|
max += plane.normal.z * this.min.z;
|
|
|
|
}
|
|
|
|
return ( min <= plane.constant && max >= plane.constant );
|
|
|
|
},
|
|
|
|
clampPoint: function ( point, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.copy( point ).clamp( this.min, this.max );
|
|
|
|
},
|
|
|
|
distanceToPoint: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function distanceToPoint( point ) {
|
|
|
|
var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
|
|
return clampedPoint.sub( point ).length();
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
getBoundingSphere: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function getBoundingSphere( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Sphere();
|
|
|
|
this.getCenter( result.center );
|
|
|
|
result.radius = this.getSize( v1 ).length() * 0.5;
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersect: function ( box ) {
|
|
|
|
this.min.max( box.min );
|
|
this.max.min( box.max );
|
|
|
|
// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.
|
|
if( this.isEmpty() ) this.makeEmpty();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
union: function ( box ) {
|
|
|
|
this.min.min( box.min );
|
|
this.max.max( box.max );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyMatrix4: function () {
|
|
|
|
var points = [
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3(),
|
|
new Vector3()
|
|
];
|
|
|
|
return function applyMatrix4( matrix ) {
|
|
|
|
// transform of empty box is an empty box.
|
|
if( this.isEmpty() ) return this;
|
|
|
|
// NOTE: I am using a binary pattern to specify all 2^3 combinations below
|
|
points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
|
|
points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
|
|
points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
|
|
points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
|
|
points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
|
|
points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
|
|
points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
|
|
points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111
|
|
|
|
this.setFromPoints( points );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translate: function ( offset ) {
|
|
|
|
this.min.add( offset );
|
|
this.max.add( offset );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( box ) {
|
|
|
|
return box.min.equals( this.min ) && box.max.equals( this.max );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Sphere( center, radius ) {
|
|
|
|
this.center = ( center !== undefined ) ? center : new Vector3();
|
|
this.radius = ( radius !== undefined ) ? radius : 0;
|
|
|
|
}
|
|
|
|
Object.assign( Sphere.prototype, {
|
|
|
|
set: function ( center, radius ) {
|
|
|
|
this.center.copy( center );
|
|
this.radius = radius;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromPoints: function () {
|
|
|
|
var box = new Box3();
|
|
|
|
return function setFromPoints( points, optionalCenter ) {
|
|
|
|
var center = this.center;
|
|
|
|
if ( optionalCenter !== undefined ) {
|
|
|
|
center.copy( optionalCenter );
|
|
|
|
} else {
|
|
|
|
box.setFromPoints( points ).getCenter( center );
|
|
|
|
}
|
|
|
|
var maxRadiusSq = 0;
|
|
|
|
for ( var i = 0, il = points.length; i < il; i ++ ) {
|
|
|
|
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
|
|
|
|
}
|
|
|
|
this.radius = Math.sqrt( maxRadiusSq );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( sphere ) {
|
|
|
|
this.center.copy( sphere.center );
|
|
this.radius = sphere.radius;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
empty: function () {
|
|
|
|
return ( this.radius <= 0 );
|
|
|
|
},
|
|
|
|
containsPoint: function ( point ) {
|
|
|
|
return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
|
|
|
|
},
|
|
|
|
distanceToPoint: function ( point ) {
|
|
|
|
return ( point.distanceTo( this.center ) - this.radius );
|
|
|
|
},
|
|
|
|
intersectsSphere: function ( sphere ) {
|
|
|
|
var radiusSum = this.radius + sphere.radius;
|
|
|
|
return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
|
|
|
|
},
|
|
|
|
intersectsBox: function ( box ) {
|
|
|
|
return box.intersectsSphere( this );
|
|
|
|
},
|
|
|
|
intersectsPlane: function ( plane ) {
|
|
|
|
// We use the following equation to compute the signed distance from
|
|
// the center of the sphere to the plane.
|
|
//
|
|
// distance = q * n - d
|
|
//
|
|
// If this distance is greater than the radius of the sphere,
|
|
// then there is no intersection.
|
|
|
|
return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
|
|
|
|
},
|
|
|
|
clampPoint: function ( point, optionalTarget ) {
|
|
|
|
var deltaLengthSq = this.center.distanceToSquared( point );
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
result.copy( point );
|
|
|
|
if ( deltaLengthSq > ( this.radius * this.radius ) ) {
|
|
|
|
result.sub( this.center ).normalize();
|
|
result.multiplyScalar( this.radius ).add( this.center );
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
getBoundingBox: function ( optionalTarget ) {
|
|
|
|
var box = optionalTarget || new Box3();
|
|
|
|
box.set( this.center, this.center );
|
|
box.expandByScalar( this.radius );
|
|
|
|
return box;
|
|
|
|
},
|
|
|
|
applyMatrix4: function ( matrix ) {
|
|
|
|
this.center.applyMatrix4( matrix );
|
|
this.radius = this.radius * matrix.getMaxScaleOnAxis();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
translate: function ( offset ) {
|
|
|
|
this.center.add( offset );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( sphere ) {
|
|
|
|
return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author bhouston / http://clara.io
|
|
* @author tschw
|
|
*/
|
|
|
|
function Matrix3() {
|
|
|
|
this.elements = [
|
|
|
|
1, 0, 0,
|
|
0, 1, 0,
|
|
0, 0, 1
|
|
|
|
];
|
|
|
|
if ( arguments.length > 0 ) {
|
|
|
|
console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Object.assign( Matrix3.prototype, {
|
|
|
|
isMatrix3: true,
|
|
|
|
set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
|
|
|
|
var te = this.elements;
|
|
|
|
te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
|
|
te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
|
|
te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
identity: function () {
|
|
|
|
this.set(
|
|
|
|
1, 0, 0,
|
|
0, 1, 0,
|
|
0, 0, 1
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().fromArray( this.elements );
|
|
|
|
},
|
|
|
|
copy: function ( m ) {
|
|
|
|
var te = this.elements;
|
|
var me = m.elements;
|
|
|
|
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
|
|
te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
|
|
te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromMatrix4: function ( m ) {
|
|
|
|
var me = m.elements;
|
|
|
|
this.set(
|
|
|
|
me[ 0 ], me[ 4 ], me[ 8 ],
|
|
me[ 1 ], me[ 5 ], me[ 9 ],
|
|
me[ 2 ], me[ 6 ], me[ 10 ]
|
|
|
|
);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
applyToBufferAttribute: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function applyToBufferAttribute( attribute ) {
|
|
|
|
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
|
|
|
|
v1.x = attribute.getX( i );
|
|
v1.y = attribute.getY( i );
|
|
v1.z = attribute.getZ( i );
|
|
|
|
v1.applyMatrix3( this );
|
|
|
|
attribute.setXYZ( i, v1.x, v1.y, v1.z );
|
|
|
|
}
|
|
|
|
return attribute;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
multiply: function ( m ) {
|
|
|
|
return this.multiplyMatrices( this, m );
|
|
|
|
},
|
|
|
|
premultiply: function ( m ) {
|
|
|
|
return this.multiplyMatrices( m, this );
|
|
|
|
},
|
|
|
|
multiplyMatrices: function ( a, b ) {
|
|
|
|
var ae = a.elements;
|
|
var be = b.elements;
|
|
var te = this.elements;
|
|
|
|
var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
|
|
var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
|
|
var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
|
|
|
|
var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
|
|
var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
|
|
var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
|
|
|
|
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
|
|
te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
|
|
te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
|
|
|
|
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
|
|
te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
|
|
te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
|
|
|
|
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
|
|
te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
|
|
te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
multiplyScalar: function ( s ) {
|
|
|
|
var te = this.elements;
|
|
|
|
te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
|
|
te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
|
|
te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
determinant: function () {
|
|
|
|
var te = this.elements;
|
|
|
|
var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
|
|
d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
|
|
g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
|
|
|
|
return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
|
|
|
|
},
|
|
|
|
getInverse: function ( matrix, throwOnDegenerate ) {
|
|
|
|
if ( matrix && matrix.isMatrix4 ) {
|
|
|
|
console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );
|
|
|
|
}
|
|
|
|
var me = matrix.elements,
|
|
te = this.elements,
|
|
|
|
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
|
|
n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
|
|
n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
|
|
|
|
t11 = n33 * n22 - n32 * n23,
|
|
t12 = n32 * n13 - n33 * n12,
|
|
t13 = n23 * n12 - n22 * n13,
|
|
|
|
det = n11 * t11 + n21 * t12 + n31 * t13;
|
|
|
|
if ( det === 0 ) {
|
|
|
|
var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";
|
|
|
|
if ( throwOnDegenerate === true ) {
|
|
|
|
throw new Error( msg );
|
|
|
|
} else {
|
|
|
|
console.warn( msg );
|
|
|
|
}
|
|
|
|
return this.identity();
|
|
|
|
}
|
|
|
|
var detInv = 1 / det;
|
|
|
|
te[ 0 ] = t11 * detInv;
|
|
te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
|
|
te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
|
|
|
|
te[ 3 ] = t12 * detInv;
|
|
te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
|
|
te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
|
|
|
|
te[ 6 ] = t13 * detInv;
|
|
te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
|
|
te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
transpose: function () {
|
|
|
|
var tmp, m = this.elements;
|
|
|
|
tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
|
|
tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
|
|
tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getNormalMatrix: function ( matrix4 ) {
|
|
|
|
return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
|
|
|
|
},
|
|
|
|
transposeIntoArray: function ( r ) {
|
|
|
|
var m = this.elements;
|
|
|
|
r[ 0 ] = m[ 0 ];
|
|
r[ 1 ] = m[ 3 ];
|
|
r[ 2 ] = m[ 6 ];
|
|
r[ 3 ] = m[ 1 ];
|
|
r[ 4 ] = m[ 4 ];
|
|
r[ 5 ] = m[ 7 ];
|
|
r[ 6 ] = m[ 2 ];
|
|
r[ 7 ] = m[ 5 ];
|
|
r[ 8 ] = m[ 8 ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( matrix ) {
|
|
|
|
var te = this.elements;
|
|
var me = matrix.elements;
|
|
|
|
for ( var i = 0; i < 9; i ++ ) {
|
|
|
|
if ( te[ i ] !== me[ i ] ) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
fromArray: function ( array, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
for ( var i = 0; i < 9; i ++ ) {
|
|
|
|
this.elements[ i ] = array[ i + offset ];
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
var te = this.elements;
|
|
|
|
array[ offset ] = te[ 0 ];
|
|
array[ offset + 1 ] = te[ 1 ];
|
|
array[ offset + 2 ] = te[ 2 ];
|
|
|
|
array[ offset + 3 ] = te[ 3 ];
|
|
array[ offset + 4 ] = te[ 4 ];
|
|
array[ offset + 5 ] = te[ 5 ];
|
|
|
|
array[ offset + 6 ] = te[ 6 ];
|
|
array[ offset + 7 ] = te[ 7 ];
|
|
array[ offset + 8 ] = te[ 8 ];
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Plane( normal, constant ) {
|
|
|
|
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
|
|
this.constant = ( constant !== undefined ) ? constant : 0;
|
|
|
|
}
|
|
|
|
Object.assign( Plane.prototype, {
|
|
|
|
set: function ( normal, constant ) {
|
|
|
|
this.normal.copy( normal );
|
|
this.constant = constant;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setComponents: function ( x, y, z, w ) {
|
|
|
|
this.normal.set( x, y, z );
|
|
this.constant = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromNormalAndCoplanarPoint: function ( normal, point ) {
|
|
|
|
this.normal.copy( normal );
|
|
this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromCoplanarPoints: function () {
|
|
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
|
|
return function setFromCoplanarPoints( a, b, c ) {
|
|
|
|
var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
|
|
|
|
// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
|
|
|
|
this.setFromNormalAndCoplanarPoint( normal, a );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( plane ) {
|
|
|
|
this.normal.copy( plane.normal );
|
|
this.constant = plane.constant;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
// Note: will lead to a divide by zero if the plane is invalid.
|
|
|
|
var inverseNormalLength = 1.0 / this.normal.length();
|
|
this.normal.multiplyScalar( inverseNormalLength );
|
|
this.constant *= inverseNormalLength;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
negate: function () {
|
|
|
|
this.constant *= - 1;
|
|
this.normal.negate();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
distanceToPoint: function ( point ) {
|
|
|
|
return this.normal.dot( point ) + this.constant;
|
|
|
|
},
|
|
|
|
distanceToSphere: function ( sphere ) {
|
|
|
|
return this.distanceToPoint( sphere.center ) - sphere.radius;
|
|
|
|
},
|
|
|
|
projectPoint: function ( point, optionalTarget ) {
|
|
|
|
return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
|
|
|
|
},
|
|
|
|
orthoPoint: function ( point, optionalTarget ) {
|
|
|
|
var perpendicularMagnitude = this.distanceToPoint( point );
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
|
|
|
|
},
|
|
|
|
intersectLine: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function intersectLine( line, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
var direction = line.delta( v1 );
|
|
|
|
var denominator = this.normal.dot( direction );
|
|
|
|
if ( denominator === 0 ) {
|
|
|
|
// line is coplanar, return origin
|
|
if ( this.distanceToPoint( line.start ) === 0 ) {
|
|
|
|
return result.copy( line.start );
|
|
|
|
}
|
|
|
|
// Unsure if this is the correct method to handle this case.
|
|
return undefined;
|
|
|
|
}
|
|
|
|
var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
|
|
|
|
if ( t < 0 || t > 1 ) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
return result.copy( direction ).multiplyScalar( t ).add( line.start );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersectsLine: function ( line ) {
|
|
|
|
// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
|
|
|
|
var startSign = this.distanceToPoint( line.start );
|
|
var endSign = this.distanceToPoint( line.end );
|
|
|
|
return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
|
|
|
|
},
|
|
|
|
intersectsBox: function ( box ) {
|
|
|
|
return box.intersectsPlane( this );
|
|
|
|
},
|
|
|
|
intersectsSphere: function ( sphere ) {
|
|
|
|
return sphere.intersectsPlane( this );
|
|
|
|
},
|
|
|
|
coplanarPoint: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.copy( this.normal ).multiplyScalar( - this.constant );
|
|
|
|
},
|
|
|
|
applyMatrix4: function () {
|
|
|
|
var v1 = new Vector3();
|
|
var m1 = new Matrix3();
|
|
|
|
return function applyMatrix4( matrix, optionalNormalMatrix ) {
|
|
|
|
var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
|
|
|
|
// transform normal based on theory here:
|
|
// http://www.songho.ca/opengl/gl_normaltransform.html
|
|
var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
|
|
var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
|
|
|
|
// recalculate constant (like in setFromNormalAndCoplanarPoint)
|
|
this.constant = - referencePoint.dot( normal );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translate: function ( offset ) {
|
|
|
|
this.constant = this.constant - offset.dot( this.normal );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( plane ) {
|
|
|
|
return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Frustum( p0, p1, p2, p3, p4, p5 ) {
|
|
|
|
this.planes = [
|
|
|
|
( p0 !== undefined ) ? p0 : new Plane(),
|
|
( p1 !== undefined ) ? p1 : new Plane(),
|
|
( p2 !== undefined ) ? p2 : new Plane(),
|
|
( p3 !== undefined ) ? p3 : new Plane(),
|
|
( p4 !== undefined ) ? p4 : new Plane(),
|
|
( p5 !== undefined ) ? p5 : new Plane()
|
|
|
|
];
|
|
|
|
}
|
|
|
|
Object.assign( Frustum.prototype, {
|
|
|
|
set: function ( p0, p1, p2, p3, p4, p5 ) {
|
|
|
|
var planes = this.planes;
|
|
|
|
planes[ 0 ].copy( p0 );
|
|
planes[ 1 ].copy( p1 );
|
|
planes[ 2 ].copy( p2 );
|
|
planes[ 3 ].copy( p3 );
|
|
planes[ 4 ].copy( p4 );
|
|
planes[ 5 ].copy( p5 );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( frustum ) {
|
|
|
|
var planes = this.planes;
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
planes[ i ].copy( frustum.planes[ i ] );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromMatrix: function ( m ) {
|
|
|
|
var planes = this.planes;
|
|
var me = m.elements;
|
|
var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
|
|
var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
|
|
var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
|
|
var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
|
|
|
|
planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
|
|
planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
|
|
planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
|
|
planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
|
|
planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
|
|
planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
intersectsObject: function () {
|
|
|
|
var sphere = new Sphere();
|
|
|
|
return function intersectsObject( object ) {
|
|
|
|
var geometry = object.geometry;
|
|
|
|
if ( geometry.boundingSphere === null )
|
|
geometry.computeBoundingSphere();
|
|
|
|
sphere.copy( geometry.boundingSphere )
|
|
.applyMatrix4( object.matrixWorld );
|
|
|
|
return this.intersectsSphere( sphere );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersectsSprite: function () {
|
|
|
|
var sphere = new Sphere();
|
|
|
|
return function intersectsSprite( sprite ) {
|
|
|
|
sphere.center.set( 0, 0, 0 );
|
|
sphere.radius = 0.7071067811865476;
|
|
sphere.applyMatrix4( sprite.matrixWorld );
|
|
|
|
return this.intersectsSphere( sphere );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersectsSphere: function ( sphere ) {
|
|
|
|
var planes = this.planes;
|
|
var center = sphere.center;
|
|
var negRadius = - sphere.radius;
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
var distance = planes[ i ].distanceToPoint( center );
|
|
|
|
if ( distance < negRadius ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
intersectsBox: function () {
|
|
|
|
var p1 = new Vector3(),
|
|
p2 = new Vector3();
|
|
|
|
return function intersectsBox( box ) {
|
|
|
|
var planes = this.planes;
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
var plane = planes[ i ];
|
|
|
|
p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
|
|
p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
|
|
p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
|
|
p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
|
|
p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
|
|
p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
|
|
|
|
var d1 = plane.distanceToPoint( p1 );
|
|
var d2 = plane.distanceToPoint( p2 );
|
|
|
|
// if both outside plane, no intersection
|
|
|
|
if ( d1 < 0 && d2 < 0 ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
containsPoint: function ( point ) {
|
|
|
|
var planes = this.planes;
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
if ( planes[ i ].distanceToPoint( point ) < 0 ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
|
|
|
|
var _gl = _renderer.context,
|
|
_state = _renderer.state,
|
|
_frustum = new Frustum(),
|
|
_projScreenMatrix = new Matrix4(),
|
|
|
|
_lightShadows = _lights.shadows,
|
|
|
|
_shadowMapSize = new Vector2(),
|
|
_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),
|
|
|
|
_lookTarget = new Vector3(),
|
|
_lightPositionWorld = new Vector3(),
|
|
|
|
_MorphingFlag = 1,
|
|
_SkinningFlag = 2,
|
|
|
|
_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,
|
|
|
|
_depthMaterials = new Array( _NumberOfMaterialVariants ),
|
|
_distanceMaterials = new Array( _NumberOfMaterialVariants ),
|
|
|
|
_materialCache = {};
|
|
|
|
var cubeDirections = [
|
|
new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
|
|
new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
|
|
];
|
|
|
|
var cubeUps = [
|
|
new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
|
|
new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
|
|
];
|
|
|
|
var cube2DViewPorts = [
|
|
new Vector4(), new Vector4(), new Vector4(),
|
|
new Vector4(), new Vector4(), new Vector4()
|
|
];
|
|
|
|
// init
|
|
|
|
var depthMaterialTemplate = new MeshDepthMaterial();
|
|
depthMaterialTemplate.depthPacking = RGBADepthPacking;
|
|
depthMaterialTemplate.clipping = true;
|
|
|
|
var distanceShader = ShaderLib[ "distanceRGBA" ];
|
|
var distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );
|
|
|
|
for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
|
|
|
|
var useMorphing = ( i & _MorphingFlag ) !== 0;
|
|
var useSkinning = ( i & _SkinningFlag ) !== 0;
|
|
|
|
var depthMaterial = depthMaterialTemplate.clone();
|
|
depthMaterial.morphTargets = useMorphing;
|
|
depthMaterial.skinning = useSkinning;
|
|
|
|
_depthMaterials[ i ] = depthMaterial;
|
|
|
|
var distanceMaterial = new ShaderMaterial( {
|
|
defines: {
|
|
'USE_SHADOWMAP': ''
|
|
},
|
|
uniforms: distanceUniforms,
|
|
vertexShader: distanceShader.vertexShader,
|
|
fragmentShader: distanceShader.fragmentShader,
|
|
morphTargets: useMorphing,
|
|
skinning: useSkinning,
|
|
clipping: true
|
|
} );
|
|
|
|
_distanceMaterials[ i ] = distanceMaterial;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var scope = this;
|
|
|
|
this.enabled = false;
|
|
|
|
this.autoUpdate = true;
|
|
this.needsUpdate = false;
|
|
|
|
this.type = PCFShadowMap;
|
|
|
|
this.renderReverseSided = true;
|
|
this.renderSingleSided = true;
|
|
|
|
this.render = function ( scene, camera ) {
|
|
|
|
if ( scope.enabled === false ) return;
|
|
if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
|
|
|
|
if ( _lightShadows.length === 0 ) return;
|
|
|
|
// Set GL state for depth map.
|
|
_state.disable( _gl.BLEND );
|
|
_state.buffers.color.setClear( 1, 1, 1, 1 );
|
|
_state.buffers.depth.setTest( true );
|
|
_state.setScissorTest( false );
|
|
|
|
// render depth map
|
|
|
|
var faceCount, isPointLight;
|
|
|
|
for ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {
|
|
|
|
var light = _lightShadows[ i ];
|
|
var shadow = light.shadow;
|
|
|
|
if ( shadow === undefined ) {
|
|
|
|
console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
|
|
continue;
|
|
|
|
}
|
|
|
|
var shadowCamera = shadow.camera;
|
|
var shadowMatrix = shadow.matrix;
|
|
|
|
_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
|
|
shadowCamera.position.copy( _lightPositionWorld );
|
|
|
|
_shadowMapSize.copy( shadow.mapSize );
|
|
_shadowMapSize.min( _maxShadowMapSize );
|
|
|
|
if ( light && light.isPointLight ) {
|
|
|
|
faceCount = 6;
|
|
isPointLight = true;
|
|
|
|
var vpWidth = _shadowMapSize.x;
|
|
var vpHeight = _shadowMapSize.y;
|
|
|
|
// These viewports map a cube-map onto a 2D texture with the
|
|
// following orientation:
|
|
//
|
|
// xzXZ
|
|
// y Y
|
|
//
|
|
// X - Positive x direction
|
|
// x - Negative x direction
|
|
// Y - Positive y direction
|
|
// y - Negative y direction
|
|
// Z - Positive z direction
|
|
// z - Negative z direction
|
|
|
|
// positive X
|
|
cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
|
|
// negative X
|
|
cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
|
|
// positive Z
|
|
cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
|
|
// negative Z
|
|
cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
|
|
// positive Y
|
|
cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
|
|
// negative Y
|
|
cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
|
|
|
|
_shadowMapSize.x *= 4.0;
|
|
_shadowMapSize.y *= 2.0;
|
|
|
|
|
|
// for point lights we set the shadow matrix to be a translation-only matrix
|
|
// equal to inverse of the light's position
|
|
|
|
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
|
|
|
|
} else {
|
|
|
|
faceCount = 1;
|
|
isPointLight = false;
|
|
|
|
_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
|
|
shadowCamera.lookAt( _lookTarget );
|
|
shadowCamera.updateMatrixWorld();
|
|
shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
|
|
|
|
// compute shadow matrix
|
|
|
|
shadowMatrix.set(
|
|
0.5, 0.0, 0.0, 0.5,
|
|
0.0, 0.5, 0.0, 0.5,
|
|
0.0, 0.0, 0.5, 0.5,
|
|
0.0, 0.0, 0.0, 1.0
|
|
);
|
|
|
|
shadowMatrix.multiply( shadowCamera.projectionMatrix );
|
|
shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
|
|
|
|
}
|
|
|
|
if ( shadow.map === null ) {
|
|
|
|
var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
|
|
|
|
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
|
|
shadow.map.texture.name = light.name + ".shadowMap";
|
|
|
|
shadowCamera.updateProjectionMatrix();
|
|
|
|
}
|
|
|
|
if ( shadow.isSpotLightShadow ) {
|
|
|
|
shadow.update( light );
|
|
|
|
}
|
|
|
|
var shadowMap = shadow.map;
|
|
|
|
_renderer.setRenderTarget( shadowMap );
|
|
_renderer.clear();
|
|
|
|
// render shadow map for each cube face (if omni-directional) or
|
|
// run a single pass if not
|
|
|
|
for ( var face = 0; face < faceCount; face ++ ) {
|
|
|
|
if ( isPointLight ) {
|
|
|
|
_lookTarget.copy( shadowCamera.position );
|
|
_lookTarget.add( cubeDirections[ face ] );
|
|
shadowCamera.up.copy( cubeUps[ face ] );
|
|
shadowCamera.lookAt( _lookTarget );
|
|
shadowCamera.updateMatrixWorld();
|
|
shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
|
|
|
|
var vpDimensions = cube2DViewPorts[ face ];
|
|
_state.viewport( vpDimensions );
|
|
|
|
}
|
|
|
|
// update camera matrices and frustum
|
|
|
|
_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
|
|
_frustum.setFromMatrix( _projScreenMatrix );
|
|
|
|
// set object matrices & frustum culling
|
|
|
|
renderObject( scene, camera, shadowCamera, isPointLight );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Restore GL state.
|
|
var clearColor = _renderer.getClearColor();
|
|
var clearAlpha = _renderer.getClearAlpha();
|
|
_renderer.setClearColor( clearColor, clearAlpha );
|
|
|
|
scope.needsUpdate = false;
|
|
|
|
};
|
|
|
|
function getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {
|
|
|
|
var geometry = object.geometry;
|
|
|
|
var result = null;
|
|
|
|
var materialVariants = _depthMaterials;
|
|
var customMaterial = object.customDepthMaterial;
|
|
|
|
if ( isPointLight ) {
|
|
|
|
materialVariants = _distanceMaterials;
|
|
customMaterial = object.customDistanceMaterial;
|
|
|
|
}
|
|
|
|
if ( ! customMaterial ) {
|
|
|
|
var useMorphing = false;
|
|
|
|
if ( material.morphTargets ) {
|
|
|
|
if ( geometry && geometry.isBufferGeometry ) {
|
|
|
|
useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
|
|
|
|
} else if ( geometry && geometry.isGeometry ) {
|
|
|
|
useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( object.isSkinnedMesh && material.skinning === false ) {
|
|
|
|
console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object );
|
|
|
|
}
|
|
|
|
var useSkinning = object.isSkinnedMesh && material.skinning;
|
|
|
|
var variantIndex = 0;
|
|
|
|
if ( useMorphing ) variantIndex |= _MorphingFlag;
|
|
if ( useSkinning ) variantIndex |= _SkinningFlag;
|
|
|
|
result = materialVariants[ variantIndex ];
|
|
|
|
} else {
|
|
|
|
result = customMaterial;
|
|
|
|
}
|
|
|
|
if ( _renderer.localClippingEnabled &&
|
|
material.clipShadows === true &&
|
|
material.clippingPlanes.length !== 0 ) {
|
|
|
|
// in this case we need a unique material instance reflecting the
|
|
// appropriate state
|
|
|
|
var keyA = result.uuid, keyB = material.uuid;
|
|
|
|
var materialsForVariant = _materialCache[ keyA ];
|
|
|
|
if ( materialsForVariant === undefined ) {
|
|
|
|
materialsForVariant = {};
|
|
_materialCache[ keyA ] = materialsForVariant;
|
|
|
|
}
|
|
|
|
var cachedMaterial = materialsForVariant[ keyB ];
|
|
|
|
if ( cachedMaterial === undefined ) {
|
|
|
|
cachedMaterial = result.clone();
|
|
materialsForVariant[ keyB ] = cachedMaterial;
|
|
|
|
}
|
|
|
|
result = cachedMaterial;
|
|
|
|
}
|
|
|
|
result.visible = material.visible;
|
|
result.wireframe = material.wireframe;
|
|
|
|
var side = material.side;
|
|
|
|
if ( scope.renderSingleSided && side == DoubleSide ) {
|
|
|
|
side = FrontSide;
|
|
|
|
}
|
|
|
|
if ( scope.renderReverseSided ) {
|
|
|
|
if ( side === FrontSide ) side = BackSide;
|
|
else if ( side === BackSide ) side = FrontSide;
|
|
|
|
}
|
|
|
|
result.side = side;
|
|
|
|
result.clipShadows = material.clipShadows;
|
|
result.clippingPlanes = material.clippingPlanes;
|
|
|
|
result.wireframeLinewidth = material.wireframeLinewidth;
|
|
result.linewidth = material.linewidth;
|
|
|
|
if ( isPointLight && result.uniforms.lightPos !== undefined ) {
|
|
|
|
result.uniforms.lightPos.value.copy( lightPositionWorld );
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
function renderObject( object, camera, shadowCamera, isPointLight ) {
|
|
|
|
if ( object.visible === false ) return;
|
|
|
|
var visible = object.layers.test( camera.layers );
|
|
|
|
if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
|
|
|
|
if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
|
|
|
|
object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
|
|
|
|
var geometry = _objects.update( object );
|
|
var material = object.material;
|
|
|
|
if ( Array.isArray( material ) ) {
|
|
|
|
var groups = geometry.groups;
|
|
|
|
for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
|
|
|
|
var group = groups[ k ];
|
|
var groupMaterial = material[ group.materialIndex ];
|
|
|
|
if ( groupMaterial && groupMaterial.visible ) {
|
|
|
|
var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
|
|
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( material.visible ) {
|
|
|
|
var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
|
|
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var children = object.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
renderObject( children[ i ], camera, shadowCamera, isPointLight );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Ray( origin, direction ) {
|
|
|
|
this.origin = ( origin !== undefined ) ? origin : new Vector3();
|
|
this.direction = ( direction !== undefined ) ? direction : new Vector3();
|
|
|
|
}
|
|
|
|
Object.assign( Ray.prototype, {
|
|
|
|
set: function ( origin, direction ) {
|
|
|
|
this.origin.copy( origin );
|
|
this.direction.copy( direction );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( ray ) {
|
|
|
|
this.origin.copy( ray.origin );
|
|
this.direction.copy( ray.direction );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
at: function ( t, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
return result.copy( this.direction ).multiplyScalar( t ).add( this.origin );
|
|
|
|
},
|
|
|
|
lookAt: function ( v ) {
|
|
|
|
this.direction.copy( v ).sub( this.origin ).normalize();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
recast: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function recast( t ) {
|
|
|
|
this.origin.copy( this.at( t, v1 ) );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
closestPointToPoint: function ( point, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
result.subVectors( point, this.origin );
|
|
var directionDistance = result.dot( this.direction );
|
|
|
|
if ( directionDistance < 0 ) {
|
|
|
|
return result.copy( this.origin );
|
|
|
|
}
|
|
|
|
return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
|
|
|
|
},
|
|
|
|
distanceToPoint: function ( point ) {
|
|
|
|
return Math.sqrt( this.distanceSqToPoint( point ) );
|
|
|
|
},
|
|
|
|
distanceSqToPoint: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function distanceSqToPoint( point ) {
|
|
|
|
var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
|
|
|
|
// point behind the ray
|
|
|
|
if ( directionDistance < 0 ) {
|
|
|
|
return this.origin.distanceToSquared( point );
|
|
|
|
}
|
|
|
|
v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
|
|
|
|
return v1.distanceToSquared( point );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
distanceSqToSegment: function () {
|
|
|
|
var segCenter = new Vector3();
|
|
var segDir = new Vector3();
|
|
var diff = new Vector3();
|
|
|
|
return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
|
|
|
|
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h
|
|
// It returns the min distance between the ray and the segment
|
|
// defined by v0 and v1
|
|
// It can also set two optional targets :
|
|
// - The closest point on the ray
|
|
// - The closest point on the segment
|
|
|
|
segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
|
|
segDir.copy( v1 ).sub( v0 ).normalize();
|
|
diff.copy( this.origin ).sub( segCenter );
|
|
|
|
var segExtent = v0.distanceTo( v1 ) * 0.5;
|
|
var a01 = - this.direction.dot( segDir );
|
|
var b0 = diff.dot( this.direction );
|
|
var b1 = - diff.dot( segDir );
|
|
var c = diff.lengthSq();
|
|
var det = Math.abs( 1 - a01 * a01 );
|
|
var s0, s1, sqrDist, extDet;
|
|
|
|
if ( det > 0 ) {
|
|
|
|
// The ray and segment are not parallel.
|
|
|
|
s0 = a01 * b1 - b0;
|
|
s1 = a01 * b0 - b1;
|
|
extDet = segExtent * det;
|
|
|
|
if ( s0 >= 0 ) {
|
|
|
|
if ( s1 >= - extDet ) {
|
|
|
|
if ( s1 <= extDet ) {
|
|
|
|
// region 0
|
|
// Minimum at interior points of ray and segment.
|
|
|
|
var invDet = 1 / det;
|
|
s0 *= invDet;
|
|
s1 *= invDet;
|
|
sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
|
|
|
|
} else {
|
|
|
|
// region 1
|
|
|
|
s1 = segExtent;
|
|
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// region 5
|
|
|
|
s1 = - segExtent;
|
|
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( s1 <= - extDet ) {
|
|
|
|
// region 4
|
|
|
|
s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
|
|
s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
} else if ( s1 <= extDet ) {
|
|
|
|
// region 3
|
|
|
|
s0 = 0;
|
|
s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
sqrDist = s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
} else {
|
|
|
|
// region 2
|
|
|
|
s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
|
|
s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Ray and segment are parallel.
|
|
|
|
s1 = ( a01 > 0 ) ? - segExtent : segExtent;
|
|
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
}
|
|
|
|
if ( optionalPointOnRay ) {
|
|
|
|
optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
|
|
|
|
}
|
|
|
|
if ( optionalPointOnSegment ) {
|
|
|
|
optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );
|
|
|
|
}
|
|
|
|
return sqrDist;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersectSphere: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function intersectSphere( sphere, optionalTarget ) {
|
|
|
|
v1.subVectors( sphere.center, this.origin );
|
|
var tca = v1.dot( this.direction );
|
|
var d2 = v1.dot( v1 ) - tca * tca;
|
|
var radius2 = sphere.radius * sphere.radius;
|
|
|
|
if ( d2 > radius2 ) return null;
|
|
|
|
var thc = Math.sqrt( radius2 - d2 );
|
|
|
|
// t0 = first intersect point - entrance on front of sphere
|
|
var t0 = tca - thc;
|
|
|
|
// t1 = second intersect point - exit point on back of sphere
|
|
var t1 = tca + thc;
|
|
|
|
// test to see if both t0 and t1 are behind the ray - if so, return null
|
|
if ( t0 < 0 && t1 < 0 ) return null;
|
|
|
|
// test to see if t0 is behind the ray:
|
|
// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
|
|
// in order to always return an intersect point that is in front of the ray.
|
|
if ( t0 < 0 ) return this.at( t1, optionalTarget );
|
|
|
|
// else t0 is in front of the ray, so return the first collision point scaled by t0
|
|
return this.at( t0, optionalTarget );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
intersectsSphere: function ( sphere ) {
|
|
|
|
return this.distanceToPoint( sphere.center ) <= sphere.radius;
|
|
|
|
},
|
|
|
|
distanceToPlane: function ( plane ) {
|
|
|
|
var denominator = plane.normal.dot( this.direction );
|
|
|
|
if ( denominator === 0 ) {
|
|
|
|
// line is coplanar, return origin
|
|
if ( plane.distanceToPoint( this.origin ) === 0 ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// Null is preferable to undefined since undefined means.... it is undefined
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
|
|
|
|
// Return if the ray never intersects the plane
|
|
|
|
return t >= 0 ? t : null;
|
|
|
|
},
|
|
|
|
intersectPlane: function ( plane, optionalTarget ) {
|
|
|
|
var t = this.distanceToPlane( plane );
|
|
|
|
if ( t === null ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.at( t, optionalTarget );
|
|
|
|
},
|
|
|
|
intersectsPlane: function ( plane ) {
|
|
|
|
// check if the ray lies on the plane first
|
|
|
|
var distToPoint = plane.distanceToPoint( this.origin );
|
|
|
|
if ( distToPoint === 0 ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
var denominator = plane.normal.dot( this.direction );
|
|
|
|
if ( denominator * distToPoint < 0 ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// ray origin is behind the plane (and is pointing behind it)
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
intersectBox: function ( box, optionalTarget ) {
|
|
|
|
var tmin, tmax, tymin, tymax, tzmin, tzmax;
|
|
|
|
var invdirx = 1 / this.direction.x,
|
|
invdiry = 1 / this.direction.y,
|
|
invdirz = 1 / this.direction.z;
|
|
|
|
var origin = this.origin;
|
|
|
|
if ( invdirx >= 0 ) {
|
|
|
|
tmin = ( box.min.x - origin.x ) * invdirx;
|
|
tmax = ( box.max.x - origin.x ) * invdirx;
|
|
|
|
} else {
|
|
|
|
tmin = ( box.max.x - origin.x ) * invdirx;
|
|
tmax = ( box.min.x - origin.x ) * invdirx;
|
|
|
|
}
|
|
|
|
if ( invdiry >= 0 ) {
|
|
|
|
tymin = ( box.min.y - origin.y ) * invdiry;
|
|
tymax = ( box.max.y - origin.y ) * invdiry;
|
|
|
|
} else {
|
|
|
|
tymin = ( box.max.y - origin.y ) * invdiry;
|
|
tymax = ( box.min.y - origin.y ) * invdiry;
|
|
|
|
}
|
|
|
|
if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;
|
|
|
|
// These lines also handle the case where tmin or tmax is NaN
|
|
// (result of 0 * Infinity). x !== x returns true if x is NaN
|
|
|
|
if ( tymin > tmin || tmin !== tmin ) tmin = tymin;
|
|
|
|
if ( tymax < tmax || tmax !== tmax ) tmax = tymax;
|
|
|
|
if ( invdirz >= 0 ) {
|
|
|
|
tzmin = ( box.min.z - origin.z ) * invdirz;
|
|
tzmax = ( box.max.z - origin.z ) * invdirz;
|
|
|
|
} else {
|
|
|
|
tzmin = ( box.max.z - origin.z ) * invdirz;
|
|
tzmax = ( box.min.z - origin.z ) * invdirz;
|
|
|
|
}
|
|
|
|
if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;
|
|
|
|
if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;
|
|
|
|
if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;
|
|
|
|
//return point closest to the ray (positive side)
|
|
|
|
if ( tmax < 0 ) return null;
|
|
|
|
return this.at( tmin >= 0 ? tmin : tmax, optionalTarget );
|
|
|
|
},
|
|
|
|
intersectsBox: ( function () {
|
|
|
|
var v = new Vector3();
|
|
|
|
return function intersectsBox( box ) {
|
|
|
|
return this.intersectBox( box, v ) !== null;
|
|
|
|
};
|
|
|
|
} )(),
|
|
|
|
intersectTriangle: function () {
|
|
|
|
// Compute the offset origin, edges, and normal.
|
|
var diff = new Vector3();
|
|
var edge1 = new Vector3();
|
|
var edge2 = new Vector3();
|
|
var normal = new Vector3();
|
|
|
|
return function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {
|
|
|
|
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
|
|
|
|
edge1.subVectors( b, a );
|
|
edge2.subVectors( c, a );
|
|
normal.crossVectors( edge1, edge2 );
|
|
|
|
// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
|
|
// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
|
|
// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
|
|
// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
|
|
// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
|
|
var DdN = this.direction.dot( normal );
|
|
var sign;
|
|
|
|
if ( DdN > 0 ) {
|
|
|
|
if ( backfaceCulling ) return null;
|
|
sign = 1;
|
|
|
|
} else if ( DdN < 0 ) {
|
|
|
|
sign = - 1;
|
|
DdN = - DdN;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
diff.subVectors( this.origin, a );
|
|
var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );
|
|
|
|
// b1 < 0, no intersection
|
|
if ( DdQxE2 < 0 ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );
|
|
|
|
// b2 < 0, no intersection
|
|
if ( DdE1xQ < 0 ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
// b1+b2 > 1, no intersection
|
|
if ( DdQxE2 + DdE1xQ > DdN ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
// Line intersects triangle, check if ray does.
|
|
var QdN = - sign * diff.dot( normal );
|
|
|
|
// t < 0, no intersection
|
|
if ( QdN < 0 ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
// Ray intersects triangle.
|
|
return this.at( QdN / DdN, optionalTarget );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
applyMatrix4: function ( matrix4 ) {
|
|
|
|
this.direction.add( this.origin ).applyMatrix4( matrix4 );
|
|
this.origin.applyMatrix4( matrix4 );
|
|
this.direction.sub( this.origin );
|
|
this.direction.normalize();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( ray ) {
|
|
|
|
return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Euler( x, y, z, order ) {
|
|
|
|
this._x = x || 0;
|
|
this._y = y || 0;
|
|
this._z = z || 0;
|
|
this._order = order || Euler.DefaultOrder;
|
|
|
|
}
|
|
|
|
Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
|
|
|
|
Euler.DefaultOrder = 'XYZ';
|
|
|
|
Object.defineProperties( Euler.prototype, {
|
|
|
|
x: {
|
|
|
|
get: function () {
|
|
|
|
return this._x;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._x = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
y: {
|
|
|
|
get: function () {
|
|
|
|
return this._y;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._y = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
z: {
|
|
|
|
get: function () {
|
|
|
|
return this._z;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._z = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
order: {
|
|
|
|
get: function () {
|
|
|
|
return this._order;
|
|
|
|
},
|
|
|
|
set: function ( value ) {
|
|
|
|
this._order = value;
|
|
this.onChangeCallback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Euler.prototype, {
|
|
|
|
isEuler: true,
|
|
|
|
set: function ( x, y, z, order ) {
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._z = z;
|
|
this._order = order || this._order;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this._x, this._y, this._z, this._order );
|
|
|
|
},
|
|
|
|
copy: function ( euler ) {
|
|
|
|
this._x = euler._x;
|
|
this._y = euler._y;
|
|
this._z = euler._z;
|
|
this._order = euler._order;
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromRotationMatrix: function ( m, order, update ) {
|
|
|
|
var clamp = _Math.clamp;
|
|
|
|
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
|
|
var te = m.elements;
|
|
var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
|
|
var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
|
|
var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
|
|
|
|
order = order || this._order;
|
|
|
|
if ( order === 'XYZ' ) {
|
|
|
|
this._y = Math.asin( clamp( m13, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m13 ) < 0.99999 ) {
|
|
|
|
this._x = Math.atan2( - m23, m33 );
|
|
this._z = Math.atan2( - m12, m11 );
|
|
|
|
} else {
|
|
|
|
this._x = Math.atan2( m32, m22 );
|
|
this._z = 0;
|
|
|
|
}
|
|
|
|
} else if ( order === 'YXZ' ) {
|
|
|
|
this._x = Math.asin( - clamp( m23, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m23 ) < 0.99999 ) {
|
|
|
|
this._y = Math.atan2( m13, m33 );
|
|
this._z = Math.atan2( m21, m22 );
|
|
|
|
} else {
|
|
|
|
this._y = Math.atan2( - m31, m11 );
|
|
this._z = 0;
|
|
|
|
}
|
|
|
|
} else if ( order === 'ZXY' ) {
|
|
|
|
this._x = Math.asin( clamp( m32, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m32 ) < 0.99999 ) {
|
|
|
|
this._y = Math.atan2( - m31, m33 );
|
|
this._z = Math.atan2( - m12, m22 );
|
|
|
|
} else {
|
|
|
|
this._y = 0;
|
|
this._z = Math.atan2( m21, m11 );
|
|
|
|
}
|
|
|
|
} else if ( order === 'ZYX' ) {
|
|
|
|
this._y = Math.asin( - clamp( m31, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m31 ) < 0.99999 ) {
|
|
|
|
this._x = Math.atan2( m32, m33 );
|
|
this._z = Math.atan2( m21, m11 );
|
|
|
|
} else {
|
|
|
|
this._x = 0;
|
|
this._z = Math.atan2( - m12, m22 );
|
|
|
|
}
|
|
|
|
} else if ( order === 'YZX' ) {
|
|
|
|
this._z = Math.asin( clamp( m21, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m21 ) < 0.99999 ) {
|
|
|
|
this._x = Math.atan2( - m23, m22 );
|
|
this._y = Math.atan2( - m31, m11 );
|
|
|
|
} else {
|
|
|
|
this._x = 0;
|
|
this._y = Math.atan2( m13, m33 );
|
|
|
|
}
|
|
|
|
} else if ( order === 'XZY' ) {
|
|
|
|
this._z = Math.asin( - clamp( m12, - 1, 1 ) );
|
|
|
|
if ( Math.abs( m12 ) < 0.99999 ) {
|
|
|
|
this._x = Math.atan2( m32, m22 );
|
|
this._y = Math.atan2( m13, m11 );
|
|
|
|
} else {
|
|
|
|
this._x = Math.atan2( - m23, m33 );
|
|
this._y = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );
|
|
|
|
}
|
|
|
|
this._order = order;
|
|
|
|
if ( update !== false ) this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromQuaternion: function () {
|
|
|
|
var matrix = new Matrix4();
|
|
|
|
return function setFromQuaternion( q, order, update ) {
|
|
|
|
matrix.makeRotationFromQuaternion( q );
|
|
|
|
return this.setFromRotationMatrix( matrix, order, update );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
setFromVector3: function ( v, order ) {
|
|
|
|
return this.set( v.x, v.y, v.z, order || this._order );
|
|
|
|
},
|
|
|
|
reorder: function () {
|
|
|
|
// WARNING: this discards revolution information -bhouston
|
|
|
|
var q = new Quaternion();
|
|
|
|
return function reorder( newOrder ) {
|
|
|
|
q.setFromEuler( this );
|
|
|
|
return this.setFromQuaternion( q, newOrder );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
equals: function ( euler ) {
|
|
|
|
return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
|
|
|
|
},
|
|
|
|
fromArray: function ( array ) {
|
|
|
|
this._x = array[ 0 ];
|
|
this._y = array[ 1 ];
|
|
this._z = array[ 2 ];
|
|
if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
|
|
|
|
this.onChangeCallback();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toArray: function ( array, offset ) {
|
|
|
|
if ( array === undefined ) array = [];
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
array[ offset ] = this._x;
|
|
array[ offset + 1 ] = this._y;
|
|
array[ offset + 2 ] = this._z;
|
|
array[ offset + 3 ] = this._order;
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
toVector3: function ( optionalResult ) {
|
|
|
|
if ( optionalResult ) {
|
|
|
|
return optionalResult.set( this._x, this._y, this._z );
|
|
|
|
} else {
|
|
|
|
return new Vector3( this._x, this._y, this._z );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onChange: function ( callback ) {
|
|
|
|
this.onChangeCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
onChangeCallback: function () {}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Layers() {
|
|
|
|
this.mask = 1 | 0;
|
|
|
|
}
|
|
|
|
Object.assign( Layers.prototype, {
|
|
|
|
set: function ( channel ) {
|
|
|
|
this.mask = 1 << channel | 0;
|
|
|
|
},
|
|
|
|
enable: function ( channel ) {
|
|
|
|
this.mask |= 1 << channel | 0;
|
|
|
|
},
|
|
|
|
toggle: function ( channel ) {
|
|
|
|
this.mask ^= 1 << channel | 0;
|
|
|
|
},
|
|
|
|
disable: function ( channel ) {
|
|
|
|
this.mask &= ~ ( 1 << channel | 0 );
|
|
|
|
},
|
|
|
|
test: function ( layers ) {
|
|
|
|
return ( this.mask & layers.mask ) !== 0;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author elephantatwork / www.elephantatwork.ch
|
|
*/
|
|
|
|
var object3DId = 0;
|
|
|
|
function Object3D() {
|
|
|
|
Object.defineProperty( this, 'id', { value: object3DId ++ } );
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.name = '';
|
|
this.type = 'Object3D';
|
|
|
|
this.parent = null;
|
|
this.children = [];
|
|
|
|
this.up = Object3D.DefaultUp.clone();
|
|
|
|
var position = new Vector3();
|
|
var rotation = new Euler();
|
|
var quaternion = new Quaternion();
|
|
var scale = new Vector3( 1, 1, 1 );
|
|
|
|
function onRotationChange() {
|
|
|
|
quaternion.setFromEuler( rotation, false );
|
|
|
|
}
|
|
|
|
function onQuaternionChange() {
|
|
|
|
rotation.setFromQuaternion( quaternion, undefined, false );
|
|
|
|
}
|
|
|
|
rotation.onChange( onRotationChange );
|
|
quaternion.onChange( onQuaternionChange );
|
|
|
|
Object.defineProperties( this, {
|
|
position: {
|
|
enumerable: true,
|
|
value: position
|
|
},
|
|
rotation: {
|
|
enumerable: true,
|
|
value: rotation
|
|
},
|
|
quaternion: {
|
|
enumerable: true,
|
|
value: quaternion
|
|
},
|
|
scale: {
|
|
enumerable: true,
|
|
value: scale
|
|
},
|
|
modelViewMatrix: {
|
|
value: new Matrix4()
|
|
},
|
|
normalMatrix: {
|
|
value: new Matrix3()
|
|
}
|
|
} );
|
|
|
|
this.matrix = new Matrix4();
|
|
this.matrixWorld = new Matrix4();
|
|
|
|
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
|
|
this.matrixWorldNeedsUpdate = false;
|
|
|
|
this.layers = new Layers();
|
|
this.visible = true;
|
|
|
|
this.castShadow = false;
|
|
this.receiveShadow = false;
|
|
|
|
this.frustumCulled = true;
|
|
this.renderOrder = 0;
|
|
|
|
this.userData = {};
|
|
|
|
this.onBeforeRender = function () {};
|
|
this.onAfterRender = function () {};
|
|
|
|
}
|
|
|
|
Object3D.DefaultUp = new Vector3( 0, 1, 0 );
|
|
Object3D.DefaultMatrixAutoUpdate = true;
|
|
|
|
Object.assign( Object3D.prototype, EventDispatcher.prototype, {
|
|
|
|
isObject3D: true,
|
|
|
|
applyMatrix: function ( matrix ) {
|
|
|
|
this.matrix.multiplyMatrices( matrix, this.matrix );
|
|
|
|
this.matrix.decompose( this.position, this.quaternion, this.scale );
|
|
|
|
},
|
|
|
|
setRotationFromAxisAngle: function ( axis, angle ) {
|
|
|
|
// assumes axis is normalized
|
|
|
|
this.quaternion.setFromAxisAngle( axis, angle );
|
|
|
|
},
|
|
|
|
setRotationFromEuler: function ( euler ) {
|
|
|
|
this.quaternion.setFromEuler( euler, true );
|
|
|
|
},
|
|
|
|
setRotationFromMatrix: function ( m ) {
|
|
|
|
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
|
|
this.quaternion.setFromRotationMatrix( m );
|
|
|
|
},
|
|
|
|
setRotationFromQuaternion: function ( q ) {
|
|
|
|
// assumes q is normalized
|
|
|
|
this.quaternion.copy( q );
|
|
|
|
},
|
|
|
|
rotateOnAxis: function () {
|
|
|
|
// rotate object on axis in object space
|
|
// axis is assumed to be normalized
|
|
|
|
var q1 = new Quaternion();
|
|
|
|
return function rotateOnAxis( axis, angle ) {
|
|
|
|
q1.setFromAxisAngle( axis, angle );
|
|
|
|
this.quaternion.multiply( q1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateX: function () {
|
|
|
|
var v1 = new Vector3( 1, 0, 0 );
|
|
|
|
return function rotateX( angle ) {
|
|
|
|
return this.rotateOnAxis( v1, angle );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateY: function () {
|
|
|
|
var v1 = new Vector3( 0, 1, 0 );
|
|
|
|
return function rotateY( angle ) {
|
|
|
|
return this.rotateOnAxis( v1, angle );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateZ: function () {
|
|
|
|
var v1 = new Vector3( 0, 0, 1 );
|
|
|
|
return function rotateZ( angle ) {
|
|
|
|
return this.rotateOnAxis( v1, angle );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translateOnAxis: function () {
|
|
|
|
// translate object by distance along axis in object space
|
|
// axis is assumed to be normalized
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function translateOnAxis( axis, distance ) {
|
|
|
|
v1.copy( axis ).applyQuaternion( this.quaternion );
|
|
|
|
this.position.add( v1.multiplyScalar( distance ) );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translateX: function () {
|
|
|
|
var v1 = new Vector3( 1, 0, 0 );
|
|
|
|
return function translateX( distance ) {
|
|
|
|
return this.translateOnAxis( v1, distance );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translateY: function () {
|
|
|
|
var v1 = new Vector3( 0, 1, 0 );
|
|
|
|
return function translateY( distance ) {
|
|
|
|
return this.translateOnAxis( v1, distance );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translateZ: function () {
|
|
|
|
var v1 = new Vector3( 0, 0, 1 );
|
|
|
|
return function translateZ( distance ) {
|
|
|
|
return this.translateOnAxis( v1, distance );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
localToWorld: function ( vector ) {
|
|
|
|
return vector.applyMatrix4( this.matrixWorld );
|
|
|
|
},
|
|
|
|
worldToLocal: function () {
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function worldToLocal( vector ) {
|
|
|
|
return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
lookAt: function () {
|
|
|
|
// This routine does not support objects with rotated and/or translated parent(s)
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function lookAt( vector ) {
|
|
|
|
if ( this.isCamera ) {
|
|
|
|
m1.lookAt( this.position, vector, this.up );
|
|
|
|
} else {
|
|
|
|
m1.lookAt( vector, this.position, this.up );
|
|
|
|
}
|
|
|
|
this.quaternion.setFromRotationMatrix( m1 );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
add: function ( object ) {
|
|
|
|
if ( arguments.length > 1 ) {
|
|
|
|
for ( var i = 0; i < arguments.length; i ++ ) {
|
|
|
|
this.add( arguments[ i ] );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
if ( object === this ) {
|
|
|
|
console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
|
|
return this;
|
|
|
|
}
|
|
|
|
if ( ( object && object.isObject3D ) ) {
|
|
|
|
if ( object.parent !== null ) {
|
|
|
|
object.parent.remove( object );
|
|
|
|
}
|
|
|
|
object.parent = this;
|
|
object.dispatchEvent( { type: 'added' } );
|
|
|
|
this.children.push( object );
|
|
|
|
} else {
|
|
|
|
console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
remove: function ( object ) {
|
|
|
|
if ( arguments.length > 1 ) {
|
|
|
|
for ( var i = 0; i < arguments.length; i ++ ) {
|
|
|
|
this.remove( arguments[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var index = this.children.indexOf( object );
|
|
|
|
if ( index !== - 1 ) {
|
|
|
|
object.parent = null;
|
|
|
|
object.dispatchEvent( { type: 'removed' } );
|
|
|
|
this.children.splice( index, 1 );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getObjectById: function ( id ) {
|
|
|
|
return this.getObjectByProperty( 'id', id );
|
|
|
|
},
|
|
|
|
getObjectByName: function ( name ) {
|
|
|
|
return this.getObjectByProperty( 'name', name );
|
|
|
|
},
|
|
|
|
getObjectByProperty: function ( name, value ) {
|
|
|
|
if ( this[ name ] === value ) return this;
|
|
|
|
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
|
|
|
|
var child = this.children[ i ];
|
|
var object = child.getObjectByProperty( name, value );
|
|
|
|
if ( object !== undefined ) {
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
},
|
|
|
|
getWorldPosition: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
this.updateMatrixWorld( true );
|
|
|
|
return result.setFromMatrixPosition( this.matrixWorld );
|
|
|
|
},
|
|
|
|
getWorldQuaternion: function () {
|
|
|
|
var position = new Vector3();
|
|
var scale = new Vector3();
|
|
|
|
return function getWorldQuaternion( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Quaternion();
|
|
|
|
this.updateMatrixWorld( true );
|
|
|
|
this.matrixWorld.decompose( position, result, scale );
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
getWorldRotation: function () {
|
|
|
|
var quaternion = new Quaternion();
|
|
|
|
return function getWorldRotation( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Euler();
|
|
|
|
this.getWorldQuaternion( quaternion );
|
|
|
|
return result.setFromQuaternion( quaternion, this.rotation.order, false );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
getWorldScale: function () {
|
|
|
|
var position = new Vector3();
|
|
var quaternion = new Quaternion();
|
|
|
|
return function getWorldScale( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
this.updateMatrixWorld( true );
|
|
|
|
this.matrixWorld.decompose( position, quaternion, result );
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
getWorldDirection: function () {
|
|
|
|
var quaternion = new Quaternion();
|
|
|
|
return function getWorldDirection( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
this.getWorldQuaternion( quaternion );
|
|
|
|
return result.set( 0, 0, 1 ).applyQuaternion( quaternion );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
raycast: function () {},
|
|
|
|
traverse: function ( callback ) {
|
|
|
|
callback( this );
|
|
|
|
var children = this.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
children[ i ].traverse( callback );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
traverseVisible: function ( callback ) {
|
|
|
|
if ( this.visible === false ) return;
|
|
|
|
callback( this );
|
|
|
|
var children = this.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
children[ i ].traverseVisible( callback );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
traverseAncestors: function ( callback ) {
|
|
|
|
var parent = this.parent;
|
|
|
|
if ( parent !== null ) {
|
|
|
|
callback( parent );
|
|
|
|
parent.traverseAncestors( callback );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
updateMatrix: function () {
|
|
|
|
this.matrix.compose( this.position, this.quaternion, this.scale );
|
|
|
|
this.matrixWorldNeedsUpdate = true;
|
|
|
|
},
|
|
|
|
updateMatrixWorld: function ( force ) {
|
|
|
|
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
|
|
|
if ( this.matrixWorldNeedsUpdate || force ) {
|
|
|
|
if ( this.parent === null ) {
|
|
|
|
this.matrixWorld.copy( this.matrix );
|
|
|
|
} else {
|
|
|
|
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
|
|
|
|
}
|
|
|
|
this.matrixWorldNeedsUpdate = false;
|
|
|
|
force = true;
|
|
|
|
}
|
|
|
|
// update children
|
|
|
|
var children = this.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
children[ i ].updateMatrixWorld( force );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
// meta is '' when called from JSON.stringify
|
|
var isRootObject = ( meta === undefined || meta === '' );
|
|
|
|
var output = {};
|
|
|
|
// meta is a hash used to collect geometries, materials.
|
|
// not providing it implies that this is the root object
|
|
// being serialized.
|
|
if ( isRootObject ) {
|
|
|
|
// initialize meta obj
|
|
meta = {
|
|
geometries: {},
|
|
materials: {},
|
|
textures: {},
|
|
images: {}
|
|
};
|
|
|
|
output.metadata = {
|
|
version: 4.5,
|
|
type: 'Object',
|
|
generator: 'Object3D.toJSON'
|
|
};
|
|
|
|
}
|
|
|
|
// standard Object3D serialization
|
|
|
|
var object = {};
|
|
|
|
object.uuid = this.uuid;
|
|
object.type = this.type;
|
|
|
|
if ( this.name !== '' ) object.name = this.name;
|
|
if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
|
|
if ( this.castShadow === true ) object.castShadow = true;
|
|
if ( this.receiveShadow === true ) object.receiveShadow = true;
|
|
if ( this.visible === false ) object.visible = false;
|
|
|
|
object.matrix = this.matrix.toArray();
|
|
|
|
//
|
|
|
|
function serialize( library, element ) {
|
|
|
|
if ( library[ element.uuid ] === undefined ) {
|
|
|
|
library[ element.uuid ] = element.toJSON( meta );
|
|
|
|
}
|
|
|
|
return element.uuid;
|
|
|
|
}
|
|
|
|
if ( this.geometry !== undefined ) {
|
|
|
|
object.geometry = serialize( meta.geometries, this.geometry );
|
|
|
|
}
|
|
|
|
if ( this.material !== undefined ) {
|
|
|
|
if ( Array.isArray( this.material ) ) {
|
|
|
|
var uuids = [];
|
|
|
|
for ( var i = 0, l = this.material.length; i < l; i ++ ) {
|
|
|
|
uuids.push( serialize( meta.materials, this.material[ i ] ) );
|
|
|
|
}
|
|
|
|
object.material = uuids;
|
|
|
|
} else {
|
|
|
|
object.material = serialize( meta.materials, this.material );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
if ( this.children.length > 0 ) {
|
|
|
|
object.children = [];
|
|
|
|
for ( var i = 0; i < this.children.length; i ++ ) {
|
|
|
|
object.children.push( this.children[ i ].toJSON( meta ).object );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( isRootObject ) {
|
|
|
|
var geometries = extractFromCache( meta.geometries );
|
|
var materials = extractFromCache( meta.materials );
|
|
var textures = extractFromCache( meta.textures );
|
|
var images = extractFromCache( meta.images );
|
|
|
|
if ( geometries.length > 0 ) output.geometries = geometries;
|
|
if ( materials.length > 0 ) output.materials = materials;
|
|
if ( textures.length > 0 ) output.textures = textures;
|
|
if ( images.length > 0 ) output.images = images;
|
|
|
|
}
|
|
|
|
output.object = object;
|
|
|
|
return output;
|
|
|
|
// extract data from the cache hash
|
|
// remove metadata on each item
|
|
// and return as array
|
|
function extractFromCache( cache ) {
|
|
|
|
var values = [];
|
|
for ( var key in cache ) {
|
|
|
|
var data = cache[ key ];
|
|
delete data.metadata;
|
|
values.push( data );
|
|
|
|
}
|
|
return values;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
clone: function ( recursive ) {
|
|
|
|
return new this.constructor().copy( this, recursive );
|
|
|
|
},
|
|
|
|
copy: function ( source, recursive ) {
|
|
|
|
if ( recursive === undefined ) recursive = true;
|
|
|
|
this.name = source.name;
|
|
|
|
this.up.copy( source.up );
|
|
|
|
this.position.copy( source.position );
|
|
this.quaternion.copy( source.quaternion );
|
|
this.scale.copy( source.scale );
|
|
|
|
this.matrix.copy( source.matrix );
|
|
this.matrixWorld.copy( source.matrixWorld );
|
|
|
|
this.matrixAutoUpdate = source.matrixAutoUpdate;
|
|
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
|
|
|
|
this.layers.mask = source.layers.mask;
|
|
this.visible = source.visible;
|
|
|
|
this.castShadow = source.castShadow;
|
|
this.receiveShadow = source.receiveShadow;
|
|
|
|
this.frustumCulled = source.frustumCulled;
|
|
this.renderOrder = source.renderOrder;
|
|
|
|
this.userData = JSON.parse( JSON.stringify( source.userData ) );
|
|
|
|
if ( recursive === true ) {
|
|
|
|
for ( var i = 0; i < source.children.length; i ++ ) {
|
|
|
|
var child = source.children[ i ];
|
|
this.add( child.clone() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
function Line3( start, end ) {
|
|
|
|
this.start = ( start !== undefined ) ? start : new Vector3();
|
|
this.end = ( end !== undefined ) ? end : new Vector3();
|
|
|
|
}
|
|
|
|
Object.assign( Line3.prototype, {
|
|
|
|
set: function ( start, end ) {
|
|
|
|
this.start.copy( start );
|
|
this.end.copy( end );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( line ) {
|
|
|
|
this.start.copy( line.start );
|
|
this.end.copy( line.end );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getCenter: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
|
|
|
|
},
|
|
|
|
delta: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.subVectors( this.end, this.start );
|
|
|
|
},
|
|
|
|
distanceSq: function () {
|
|
|
|
return this.start.distanceToSquared( this.end );
|
|
|
|
},
|
|
|
|
distance: function () {
|
|
|
|
return this.start.distanceTo( this.end );
|
|
|
|
},
|
|
|
|
at: function ( t, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
return this.delta( result ).multiplyScalar( t ).add( this.start );
|
|
|
|
},
|
|
|
|
closestPointToPointParameter: function () {
|
|
|
|
var startP = new Vector3();
|
|
var startEnd = new Vector3();
|
|
|
|
return function closestPointToPointParameter( point, clampToLine ) {
|
|
|
|
startP.subVectors( point, this.start );
|
|
startEnd.subVectors( this.end, this.start );
|
|
|
|
var startEnd2 = startEnd.dot( startEnd );
|
|
var startEnd_startP = startEnd.dot( startP );
|
|
|
|
var t = startEnd_startP / startEnd2;
|
|
|
|
if ( clampToLine ) {
|
|
|
|
t = _Math.clamp( t, 0, 1 );
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
|
|
|
|
var t = this.closestPointToPointParameter( point, clampToLine );
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
return this.delta( result ).multiplyScalar( t ).add( this.start );
|
|
|
|
},
|
|
|
|
applyMatrix4: function ( matrix ) {
|
|
|
|
this.start.applyMatrix4( matrix );
|
|
this.end.applyMatrix4( matrix );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
equals: function ( line ) {
|
|
|
|
return line.start.equals( this.start ) && line.end.equals( this.end );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Triangle( a, b, c ) {
|
|
|
|
this.a = ( a !== undefined ) ? a : new Vector3();
|
|
this.b = ( b !== undefined ) ? b : new Vector3();
|
|
this.c = ( c !== undefined ) ? c : new Vector3();
|
|
|
|
}
|
|
|
|
Object.assign( Triangle, {
|
|
|
|
normal: function () {
|
|
|
|
var v0 = new Vector3();
|
|
|
|
return function normal( a, b, c, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
result.subVectors( c, b );
|
|
v0.subVectors( a, b );
|
|
result.cross( v0 );
|
|
|
|
var resultLengthSq = result.lengthSq();
|
|
if ( resultLengthSq > 0 ) {
|
|
|
|
return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
|
|
|
|
}
|
|
|
|
return result.set( 0, 0, 0 );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
// static/instance method to calculate barycentric coordinates
|
|
// based on: http://www.blackpawn.com/texts/pointinpoly/default.html
|
|
barycoordFromPoint: function () {
|
|
|
|
var v0 = new Vector3();
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
|
|
return function barycoordFromPoint( point, a, b, c, optionalTarget ) {
|
|
|
|
v0.subVectors( c, a );
|
|
v1.subVectors( b, a );
|
|
v2.subVectors( point, a );
|
|
|
|
var dot00 = v0.dot( v0 );
|
|
var dot01 = v0.dot( v1 );
|
|
var dot02 = v0.dot( v2 );
|
|
var dot11 = v1.dot( v1 );
|
|
var dot12 = v1.dot( v2 );
|
|
|
|
var denom = ( dot00 * dot11 - dot01 * dot01 );
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
// collinear or singular triangle
|
|
if ( denom === 0 ) {
|
|
|
|
// arbitrary location outside of triangle?
|
|
// not sure if this is the best idea, maybe should be returning undefined
|
|
return result.set( - 2, - 1, - 1 );
|
|
|
|
}
|
|
|
|
var invDenom = 1 / denom;
|
|
var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
|
|
var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
|
|
|
|
// barycentric coordinates must always sum to 1
|
|
return result.set( 1 - u - v, v, u );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
containsPoint: function () {
|
|
|
|
var v1 = new Vector3();
|
|
|
|
return function containsPoint( point, a, b, c ) {
|
|
|
|
var result = Triangle.barycoordFromPoint( point, a, b, c, v1 );
|
|
|
|
return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
|
|
|
|
};
|
|
|
|
}()
|
|
|
|
} );
|
|
|
|
Object.assign( Triangle.prototype, {
|
|
|
|
set: function ( a, b, c ) {
|
|
|
|
this.a.copy( a );
|
|
this.b.copy( b );
|
|
this.c.copy( c );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
|
|
|
|
this.a.copy( points[ i0 ] );
|
|
this.b.copy( points[ i1 ] );
|
|
this.c.copy( points[ i2 ] );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( triangle ) {
|
|
|
|
this.a.copy( triangle.a );
|
|
this.b.copy( triangle.b );
|
|
this.c.copy( triangle.c );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
area: function () {
|
|
|
|
var v0 = new Vector3();
|
|
var v1 = new Vector3();
|
|
|
|
return function area() {
|
|
|
|
v0.subVectors( this.c, this.b );
|
|
v1.subVectors( this.a, this.b );
|
|
|
|
return v0.cross( v1 ).length() * 0.5;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
midpoint: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
|
|
|
|
},
|
|
|
|
normal: function ( optionalTarget ) {
|
|
|
|
return Triangle.normal( this.a, this.b, this.c, optionalTarget );
|
|
|
|
},
|
|
|
|
plane: function ( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Plane();
|
|
|
|
return result.setFromCoplanarPoints( this.a, this.b, this.c );
|
|
|
|
},
|
|
|
|
barycoordFromPoint: function ( point, optionalTarget ) {
|
|
|
|
return Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
|
|
|
|
},
|
|
|
|
containsPoint: function ( point ) {
|
|
|
|
return Triangle.containsPoint( point, this.a, this.b, this.c );
|
|
|
|
},
|
|
|
|
closestPointToPoint: function () {
|
|
|
|
var plane = new Plane();
|
|
var edgeList = [ new Line3(), new Line3(), new Line3() ];
|
|
var projectedPoint = new Vector3();
|
|
var closestPoint = new Vector3();
|
|
|
|
return function closestPointToPoint( point, optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
var minDistance = Infinity;
|
|
|
|
// project the point onto the plane of the triangle
|
|
|
|
plane.setFromCoplanarPoints( this.a, this.b, this.c );
|
|
plane.projectPoint( point, projectedPoint );
|
|
|
|
// check if the projection lies within the triangle
|
|
|
|
if( this.containsPoint( projectedPoint ) === true ) {
|
|
|
|
// if so, this is the closest point
|
|
|
|
result.copy( projectedPoint );
|
|
|
|
} else {
|
|
|
|
// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices
|
|
|
|
edgeList[ 0 ].set( this.a, this.b );
|
|
edgeList[ 1 ].set( this.b, this.c );
|
|
edgeList[ 2 ].set( this.c, this.a );
|
|
|
|
for( var i = 0; i < edgeList.length; i ++ ) {
|
|
|
|
edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );
|
|
|
|
var distance = projectedPoint.distanceToSquared( closestPoint );
|
|
|
|
if( distance < minDistance ) {
|
|
|
|
minDistance = distance;
|
|
|
|
result.copy( closestPoint );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
equals: function ( triangle ) {
|
|
|
|
return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Face3( a, b, c, normal, color, materialIndex ) {
|
|
|
|
this.a = a;
|
|
this.b = b;
|
|
this.c = c;
|
|
|
|
this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
|
|
this.vertexNormals = Array.isArray( normal ) ? normal : [];
|
|
|
|
this.color = ( color && color.isColor ) ? color : new Color();
|
|
this.vertexColors = Array.isArray( color ) ? color : [];
|
|
|
|
this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
|
|
|
|
}
|
|
|
|
Object.assign( Face3.prototype, {
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.a = source.a;
|
|
this.b = source.b;
|
|
this.c = source.c;
|
|
|
|
this.normal.copy( source.normal );
|
|
this.color.copy( source.color );
|
|
|
|
this.materialIndex = source.materialIndex;
|
|
|
|
for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
|
|
|
|
this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
|
|
|
|
}
|
|
|
|
for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {
|
|
|
|
this.vertexColors[ i ] = source.vertexColors[ i ].clone();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* lightMap: new THREE.Texture( <Image> ),
|
|
* lightMapIntensity: <float>
|
|
*
|
|
* aoMap: new THREE.Texture( <Image> ),
|
|
* aoMapIntensity: <float>
|
|
*
|
|
* specularMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* alphaMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
|
|
* combine: THREE.Multiply,
|
|
* reflectivity: <float>,
|
|
* refractionRatio: <float>,
|
|
*
|
|
* shading: THREE.SmoothShading,
|
|
* depthTest: <bool>,
|
|
* depthWrite: <bool>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>,
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>
|
|
* }
|
|
*/
|
|
|
|
function MeshBasicMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'MeshBasicMaterial';
|
|
|
|
this.color = new Color( 0xffffff ); // emissive
|
|
|
|
this.map = null;
|
|
|
|
this.lightMap = null;
|
|
this.lightMapIntensity = 1.0;
|
|
|
|
this.aoMap = null;
|
|
this.aoMapIntensity = 1.0;
|
|
|
|
this.specularMap = null;
|
|
|
|
this.alphaMap = null;
|
|
|
|
this.envMap = null;
|
|
this.combine = MultiplyOperation;
|
|
this.reflectivity = 1;
|
|
this.refractionRatio = 0.98;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
this.wireframeLinecap = 'round';
|
|
this.wireframeLinejoin = 'round';
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshBasicMaterial.prototype = Object.create( Material.prototype );
|
|
MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
|
|
|
|
MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
|
|
|
|
MeshBasicMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
|
|
this.map = source.map;
|
|
|
|
this.lightMap = source.lightMap;
|
|
this.lightMapIntensity = source.lightMapIntensity;
|
|
|
|
this.aoMap = source.aoMap;
|
|
this.aoMapIntensity = source.aoMapIntensity;
|
|
|
|
this.specularMap = source.specularMap;
|
|
|
|
this.alphaMap = source.alphaMap;
|
|
|
|
this.envMap = source.envMap;
|
|
this.combine = source.combine;
|
|
this.reflectivity = source.reflectivity;
|
|
this.refractionRatio = source.refractionRatio;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
this.wireframeLinecap = source.wireframeLinecap;
|
|
this.wireframeLinejoin = source.wireframeLinejoin;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function BufferAttribute( array, itemSize, normalized ) {
|
|
|
|
if ( Array.isArray( array ) ) {
|
|
|
|
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
|
|
|
}
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.array = array;
|
|
this.itemSize = itemSize;
|
|
this.count = array !== undefined ? array.length / itemSize : 0;
|
|
this.normalized = normalized === true;
|
|
|
|
this.dynamic = false;
|
|
this.updateRange = { offset: 0, count: - 1 };
|
|
|
|
this.onUploadCallback = function () {};
|
|
|
|
this.version = 0;
|
|
|
|
}
|
|
|
|
Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
|
|
|
|
set: function ( value ) {
|
|
|
|
if ( value === true ) this.version ++;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( BufferAttribute.prototype, {
|
|
|
|
isBufferAttribute: true,
|
|
|
|
setArray: function ( array ) {
|
|
|
|
if ( Array.isArray( array ) ) {
|
|
|
|
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
|
|
|
}
|
|
|
|
this.count = array !== undefined ? array.length / this.itemSize : 0;
|
|
this.array = array;
|
|
|
|
},
|
|
|
|
setDynamic: function ( value ) {
|
|
|
|
this.dynamic = value;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.array = new source.array.constructor( source.array );
|
|
this.itemSize = source.itemSize;
|
|
this.count = source.count;
|
|
this.normalized = source.normalized;
|
|
|
|
this.dynamic = source.dynamic;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyAt: function ( index1, attribute, index2 ) {
|
|
|
|
index1 *= this.itemSize;
|
|
index2 *= attribute.itemSize;
|
|
|
|
for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
|
|
|
|
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyArray: function ( array ) {
|
|
|
|
this.array.set( array );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyColorsArray: function ( colors ) {
|
|
|
|
var array = this.array, offset = 0;
|
|
|
|
for ( var i = 0, l = colors.length; i < l; i ++ ) {
|
|
|
|
var color = colors[ i ];
|
|
|
|
if ( color === undefined ) {
|
|
|
|
console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
|
|
color = new Color();
|
|
|
|
}
|
|
|
|
array[ offset ++ ] = color.r;
|
|
array[ offset ++ ] = color.g;
|
|
array[ offset ++ ] = color.b;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyIndicesArray: function ( indices ) {
|
|
|
|
var array = this.array, offset = 0;
|
|
|
|
for ( var i = 0, l = indices.length; i < l; i ++ ) {
|
|
|
|
var index = indices[ i ];
|
|
|
|
array[ offset ++ ] = index.a;
|
|
array[ offset ++ ] = index.b;
|
|
array[ offset ++ ] = index.c;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyVector2sArray: function ( vectors ) {
|
|
|
|
var array = this.array, offset = 0;
|
|
|
|
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
|
|
|
var vector = vectors[ i ];
|
|
|
|
if ( vector === undefined ) {
|
|
|
|
console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
|
|
vector = new Vector2();
|
|
|
|
}
|
|
|
|
array[ offset ++ ] = vector.x;
|
|
array[ offset ++ ] = vector.y;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyVector3sArray: function ( vectors ) {
|
|
|
|
var array = this.array, offset = 0;
|
|
|
|
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
|
|
|
var vector = vectors[ i ];
|
|
|
|
if ( vector === undefined ) {
|
|
|
|
console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
|
|
vector = new Vector3();
|
|
|
|
}
|
|
|
|
array[ offset ++ ] = vector.x;
|
|
array[ offset ++ ] = vector.y;
|
|
array[ offset ++ ] = vector.z;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyVector4sArray: function ( vectors ) {
|
|
|
|
var array = this.array, offset = 0;
|
|
|
|
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
|
|
|
var vector = vectors[ i ];
|
|
|
|
if ( vector === undefined ) {
|
|
|
|
console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
|
|
vector = new Vector4();
|
|
|
|
}
|
|
|
|
array[ offset ++ ] = vector.x;
|
|
array[ offset ++ ] = vector.y;
|
|
array[ offset ++ ] = vector.z;
|
|
array[ offset ++ ] = vector.w;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
set: function ( value, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.array.set( value, offset );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getX: function ( index ) {
|
|
|
|
return this.array[ index * this.itemSize ];
|
|
|
|
},
|
|
|
|
setX: function ( index, x ) {
|
|
|
|
this.array[ index * this.itemSize ] = x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getY: function ( index ) {
|
|
|
|
return this.array[ index * this.itemSize + 1 ];
|
|
|
|
},
|
|
|
|
setY: function ( index, y ) {
|
|
|
|
this.array[ index * this.itemSize + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getZ: function ( index ) {
|
|
|
|
return this.array[ index * this.itemSize + 2 ];
|
|
|
|
},
|
|
|
|
setZ: function ( index, z ) {
|
|
|
|
this.array[ index * this.itemSize + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getW: function ( index ) {
|
|
|
|
return this.array[ index * this.itemSize + 3 ];
|
|
|
|
},
|
|
|
|
setW: function ( index, w ) {
|
|
|
|
this.array[ index * this.itemSize + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setXY: function ( index, x, y ) {
|
|
|
|
index *= this.itemSize;
|
|
|
|
this.array[ index + 0 ] = x;
|
|
this.array[ index + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setXYZ: function ( index, x, y, z ) {
|
|
|
|
index *= this.itemSize;
|
|
|
|
this.array[ index + 0 ] = x;
|
|
this.array[ index + 1 ] = y;
|
|
this.array[ index + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setXYZW: function ( index, x, y, z, w ) {
|
|
|
|
index *= this.itemSize;
|
|
|
|
this.array[ index + 0 ] = x;
|
|
this.array[ index + 1 ] = y;
|
|
this.array[ index + 2 ] = z;
|
|
this.array[ index + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
onUpload: function ( callback ) {
|
|
|
|
this.onUploadCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.array, this.itemSize ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
function Int8BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Int8Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
|
|
|
|
|
|
function Uint8BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Uint8Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
|
|
|
|
|
|
function Uint8ClampedBufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );
|
|
|
|
}
|
|
|
|
Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
|
|
|
|
|
|
function Int16BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Int16Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
|
|
|
|
|
|
function Uint16BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Uint16Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
|
|
|
|
|
|
function Int32BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Int32Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
|
|
|
|
|
|
function Uint32BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Uint32Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
|
|
|
|
|
|
function Float32BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Float32Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
|
|
|
|
|
|
function Float64BufferAttribute( array, itemSize ) {
|
|
|
|
BufferAttribute.call( this, new Float64Array( array ), itemSize );
|
|
|
|
}
|
|
|
|
Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
|
Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function DirectGeometry() {
|
|
|
|
this.indices = [];
|
|
this.vertices = [];
|
|
this.normals = [];
|
|
this.colors = [];
|
|
this.uvs = [];
|
|
this.uvs2 = [];
|
|
|
|
this.groups = [];
|
|
|
|
this.morphTargets = {};
|
|
|
|
this.skinWeights = [];
|
|
this.skinIndices = [];
|
|
|
|
// this.lineDistances = [];
|
|
|
|
this.boundingBox = null;
|
|
this.boundingSphere = null;
|
|
|
|
// update flags
|
|
|
|
this.verticesNeedUpdate = false;
|
|
this.normalsNeedUpdate = false;
|
|
this.colorsNeedUpdate = false;
|
|
this.uvsNeedUpdate = false;
|
|
this.groupsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
Object.assign( DirectGeometry.prototype, {
|
|
|
|
computeGroups: function ( geometry ) {
|
|
|
|
var group;
|
|
var groups = [];
|
|
var materialIndex = undefined;
|
|
|
|
var faces = geometry.faces;
|
|
|
|
for ( var i = 0; i < faces.length; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
// materials
|
|
|
|
if ( face.materialIndex !== materialIndex ) {
|
|
|
|
materialIndex = face.materialIndex;
|
|
|
|
if ( group !== undefined ) {
|
|
|
|
group.count = ( i * 3 ) - group.start;
|
|
groups.push( group );
|
|
|
|
}
|
|
|
|
group = {
|
|
start: i * 3,
|
|
materialIndex: materialIndex
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( group !== undefined ) {
|
|
|
|
group.count = ( i * 3 ) - group.start;
|
|
groups.push( group );
|
|
|
|
}
|
|
|
|
this.groups = groups;
|
|
|
|
},
|
|
|
|
fromGeometry: function ( geometry ) {
|
|
|
|
var faces = geometry.faces;
|
|
var vertices = geometry.vertices;
|
|
var faceVertexUvs = geometry.faceVertexUvs;
|
|
|
|
var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
|
|
var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
|
|
|
|
// morphs
|
|
|
|
var morphTargets = geometry.morphTargets;
|
|
var morphTargetsLength = morphTargets.length;
|
|
|
|
var morphTargetsPosition;
|
|
|
|
if ( morphTargetsLength > 0 ) {
|
|
|
|
morphTargetsPosition = [];
|
|
|
|
for ( var i = 0; i < morphTargetsLength; i ++ ) {
|
|
|
|
morphTargetsPosition[ i ] = [];
|
|
|
|
}
|
|
|
|
this.morphTargets.position = morphTargetsPosition;
|
|
|
|
}
|
|
|
|
var morphNormals = geometry.morphNormals;
|
|
var morphNormalsLength = morphNormals.length;
|
|
|
|
var morphTargetsNormal;
|
|
|
|
if ( morphNormalsLength > 0 ) {
|
|
|
|
morphTargetsNormal = [];
|
|
|
|
for ( var i = 0; i < morphNormalsLength; i ++ ) {
|
|
|
|
morphTargetsNormal[ i ] = [];
|
|
|
|
}
|
|
|
|
this.morphTargets.normal = morphTargetsNormal;
|
|
|
|
}
|
|
|
|
// skins
|
|
|
|
var skinIndices = geometry.skinIndices;
|
|
var skinWeights = geometry.skinWeights;
|
|
|
|
var hasSkinIndices = skinIndices.length === vertices.length;
|
|
var hasSkinWeights = skinWeights.length === vertices.length;
|
|
|
|
//
|
|
|
|
for ( var i = 0; i < faces.length; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
|
|
|
|
var vertexNormals = face.vertexNormals;
|
|
|
|
if ( vertexNormals.length === 3 ) {
|
|
|
|
this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
|
|
|
|
} else {
|
|
|
|
var normal = face.normal;
|
|
|
|
this.normals.push( normal, normal, normal );
|
|
|
|
}
|
|
|
|
var vertexColors = face.vertexColors;
|
|
|
|
if ( vertexColors.length === 3 ) {
|
|
|
|
this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
|
|
|
|
} else {
|
|
|
|
var color = face.color;
|
|
|
|
this.colors.push( color, color, color );
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexUv === true ) {
|
|
|
|
var vertexUvs = faceVertexUvs[ 0 ][ i ];
|
|
|
|
if ( vertexUvs !== undefined ) {
|
|
|
|
this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
|
|
|
|
this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexUv2 === true ) {
|
|
|
|
var vertexUvs = faceVertexUvs[ 1 ][ i ];
|
|
|
|
if ( vertexUvs !== undefined ) {
|
|
|
|
this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
|
|
|
|
this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// morphs
|
|
|
|
for ( var j = 0; j < morphTargetsLength; j ++ ) {
|
|
|
|
var morphTarget = morphTargets[ j ].vertices;
|
|
|
|
morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
|
|
|
|
}
|
|
|
|
for ( var j = 0; j < morphNormalsLength; j ++ ) {
|
|
|
|
var morphNormal = morphNormals[ j ].vertexNormals[ i ];
|
|
|
|
morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );
|
|
|
|
}
|
|
|
|
// skins
|
|
|
|
if ( hasSkinIndices ) {
|
|
|
|
this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
|
|
|
|
}
|
|
|
|
if ( hasSkinWeights ) {
|
|
|
|
this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.computeGroups( geometry );
|
|
|
|
this.verticesNeedUpdate = geometry.verticesNeedUpdate;
|
|
this.normalsNeedUpdate = geometry.normalsNeedUpdate;
|
|
this.colorsNeedUpdate = geometry.colorsNeedUpdate;
|
|
this.uvsNeedUpdate = geometry.uvsNeedUpdate;
|
|
this.groupsNeedUpdate = geometry.groupsNeedUpdate;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
function arrayMax( array ) {
|
|
|
|
if ( array.length === 0 ) return - Infinity;
|
|
|
|
var max = array[ 0 ];
|
|
|
|
for ( var i = 1, l = array.length; i < l; ++ i ) {
|
|
|
|
if ( array[ i ] > max ) max = array[ i ];
|
|
|
|
}
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author kile / http://kile.stravaganza.org/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* @author bhouston / http://clara.io
|
|
*/
|
|
|
|
var count = 0;
|
|
function GeometryIdCount() { return count++; }
|
|
|
|
function Geometry() {
|
|
|
|
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.name = '';
|
|
this.type = 'Geometry';
|
|
|
|
this.vertices = [];
|
|
this.colors = [];
|
|
this.faces = [];
|
|
this.faceVertexUvs = [[]];
|
|
|
|
this.morphTargets = [];
|
|
this.morphNormals = [];
|
|
|
|
this.skinWeights = [];
|
|
this.skinIndices = [];
|
|
|
|
this.lineDistances = [];
|
|
|
|
this.boundingBox = null;
|
|
this.boundingSphere = null;
|
|
|
|
// update flags
|
|
|
|
this.elementsNeedUpdate = false;
|
|
this.verticesNeedUpdate = false;
|
|
this.uvsNeedUpdate = false;
|
|
this.normalsNeedUpdate = false;
|
|
this.colorsNeedUpdate = false;
|
|
this.lineDistancesNeedUpdate = false;
|
|
this.groupsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
Object.assign( Geometry.prototype, EventDispatcher.prototype, {
|
|
|
|
isGeometry: true,
|
|
|
|
applyMatrix: function ( matrix ) {
|
|
|
|
var normalMatrix = new Matrix3().getNormalMatrix( matrix );
|
|
|
|
for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
|
|
|
|
var vertex = this.vertices[ i ];
|
|
vertex.applyMatrix4( matrix );
|
|
|
|
}
|
|
|
|
for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
|
|
|
|
var face = this.faces[ i ];
|
|
face.normal.applyMatrix3( normalMatrix ).normalize();
|
|
|
|
for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
|
|
|
|
face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.boundingBox !== null ) {
|
|
|
|
this.computeBoundingBox();
|
|
|
|
}
|
|
|
|
if ( this.boundingSphere !== null ) {
|
|
|
|
this.computeBoundingSphere();
|
|
|
|
}
|
|
|
|
this.verticesNeedUpdate = true;
|
|
this.normalsNeedUpdate = true;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
rotateX: function () {
|
|
|
|
// rotate geometry around world x-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateX( angle ) {
|
|
|
|
m1.makeRotationX( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateY: function () {
|
|
|
|
// rotate geometry around world y-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateY( angle ) {
|
|
|
|
m1.makeRotationY( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateZ: function () {
|
|
|
|
// rotate geometry around world z-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateZ( angle ) {
|
|
|
|
m1.makeRotationZ( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translate: function () {
|
|
|
|
// translate geometry
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function translate( x, y, z ) {
|
|
|
|
m1.makeTranslation( x, y, z );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
scale: function () {
|
|
|
|
// scale geometry
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function scale( x, y, z ) {
|
|
|
|
m1.makeScale( x, y, z );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
lookAt: function () {
|
|
|
|
var obj = new Object3D();
|
|
|
|
return function lookAt( vector ) {
|
|
|
|
obj.lookAt( vector );
|
|
|
|
obj.updateMatrix();
|
|
|
|
this.applyMatrix( obj.matrix );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
fromBufferGeometry: function ( geometry ) {
|
|
|
|
var scope = this;
|
|
|
|
var indices = geometry.index !== null ? geometry.index.array : undefined;
|
|
var attributes = geometry.attributes;
|
|
|
|
var positions = attributes.position.array;
|
|
var normals = attributes.normal !== undefined ? attributes.normal.array : undefined;
|
|
var colors = attributes.color !== undefined ? attributes.color.array : undefined;
|
|
var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
|
|
var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
|
|
|
|
if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
|
|
|
|
var tempNormals = [];
|
|
var tempUVs = [];
|
|
var tempUVs2 = [];
|
|
|
|
for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
|
|
|
|
scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );
|
|
|
|
if ( normals !== undefined ) {
|
|
|
|
tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );
|
|
|
|
}
|
|
|
|
if ( colors !== undefined ) {
|
|
|
|
scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );
|
|
|
|
}
|
|
|
|
if ( uvs !== undefined ) {
|
|
|
|
tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );
|
|
|
|
}
|
|
|
|
if ( uvs2 !== undefined ) {
|
|
|
|
tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function addFace( a, b, c, materialIndex ) {
|
|
|
|
var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];
|
|
var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];
|
|
|
|
var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
|
|
|
|
scope.faces.push( face );
|
|
|
|
if ( uvs !== undefined ) {
|
|
|
|
scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );
|
|
|
|
}
|
|
|
|
if ( uvs2 !== undefined ) {
|
|
|
|
scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var groups = geometry.groups;
|
|
|
|
if ( groups.length > 0 ) {
|
|
|
|
for ( var i = 0; i < groups.length; i ++ ) {
|
|
|
|
var group = groups[ i ];
|
|
|
|
var start = group.start;
|
|
var count = group.count;
|
|
|
|
for ( var j = start, jl = start + count; j < jl; j += 3 ) {
|
|
|
|
if ( indices !== undefined ) {
|
|
|
|
addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );
|
|
|
|
} else {
|
|
|
|
addFace( j, j + 1, j + 2, group.materialIndex );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( indices !== undefined ) {
|
|
|
|
for ( var i = 0; i < indices.length; i += 3 ) {
|
|
|
|
addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( var i = 0; i < positions.length / 3; i += 3 ) {
|
|
|
|
addFace( i, i + 1, i + 2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.computeFaceNormals();
|
|
|
|
if ( geometry.boundingBox !== null ) {
|
|
|
|
this.boundingBox = geometry.boundingBox.clone();
|
|
|
|
}
|
|
|
|
if ( geometry.boundingSphere !== null ) {
|
|
|
|
this.boundingSphere = geometry.boundingSphere.clone();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
center: function () {
|
|
|
|
this.computeBoundingBox();
|
|
|
|
var offset = this.boundingBox.getCenter().negate();
|
|
|
|
this.translate( offset.x, offset.y, offset.z );
|
|
|
|
return offset;
|
|
|
|
},
|
|
|
|
normalize: function () {
|
|
|
|
this.computeBoundingSphere();
|
|
|
|
var center = this.boundingSphere.center;
|
|
var radius = this.boundingSphere.radius;
|
|
|
|
var s = radius === 0 ? 1 : 1.0 / radius;
|
|
|
|
var matrix = new Matrix4();
|
|
matrix.set(
|
|
s, 0, 0, - s * center.x,
|
|
0, s, 0, - s * center.y,
|
|
0, 0, s, - s * center.z,
|
|
0, 0, 0, 1
|
|
);
|
|
|
|
this.applyMatrix( matrix );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
computeFaceNormals: function () {
|
|
|
|
var cb = new Vector3(), ab = new Vector3();
|
|
|
|
for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
var face = this.faces[ f ];
|
|
|
|
var vA = this.vertices[ face.a ];
|
|
var vB = this.vertices[ face.b ];
|
|
var vC = this.vertices[ face.c ];
|
|
|
|
cb.subVectors( vC, vB );
|
|
ab.subVectors( vA, vB );
|
|
cb.cross( ab );
|
|
|
|
cb.normalize();
|
|
|
|
face.normal.copy( cb );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeVertexNormals: function ( areaWeighted ) {
|
|
|
|
if ( areaWeighted === undefined ) areaWeighted = true;
|
|
|
|
var v, vl, f, fl, face, vertices;
|
|
|
|
vertices = new Array( this.vertices.length );
|
|
|
|
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
|
|
|
|
vertices[ v ] = new Vector3();
|
|
|
|
}
|
|
|
|
if ( areaWeighted ) {
|
|
|
|
// vertex normals weighted by triangle areas
|
|
// http://www.iquilezles.org/www/articles/normals/normals.htm
|
|
|
|
var vA, vB, vC;
|
|
var cb = new Vector3(), ab = new Vector3();
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
vA = this.vertices[ face.a ];
|
|
vB = this.vertices[ face.b ];
|
|
vC = this.vertices[ face.c ];
|
|
|
|
cb.subVectors( vC, vB );
|
|
ab.subVectors( vA, vB );
|
|
cb.cross( ab );
|
|
|
|
vertices[ face.a ].add( cb );
|
|
vertices[ face.b ].add( cb );
|
|
vertices[ face.c ].add( cb );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.computeFaceNormals();
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
vertices[ face.a ].add( face.normal );
|
|
vertices[ face.b ].add( face.normal );
|
|
vertices[ face.c ].add( face.normal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
|
|
|
|
vertices[ v ].normalize();
|
|
|
|
}
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
var vertexNormals = face.vertexNormals;
|
|
|
|
if ( vertexNormals.length === 3 ) {
|
|
|
|
vertexNormals[ 0 ].copy( vertices[ face.a ] );
|
|
vertexNormals[ 1 ].copy( vertices[ face.b ] );
|
|
vertexNormals[ 2 ].copy( vertices[ face.c ] );
|
|
|
|
} else {
|
|
|
|
vertexNormals[ 0 ] = vertices[ face.a ].clone();
|
|
vertexNormals[ 1 ] = vertices[ face.b ].clone();
|
|
vertexNormals[ 2 ] = vertices[ face.c ].clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.faces.length > 0 ) {
|
|
|
|
this.normalsNeedUpdate = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeFlatVertexNormals: function () {
|
|
|
|
var f, fl, face;
|
|
|
|
this.computeFaceNormals();
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
var vertexNormals = face.vertexNormals;
|
|
|
|
if ( vertexNormals.length === 3 ) {
|
|
|
|
vertexNormals[ 0 ].copy( face.normal );
|
|
vertexNormals[ 1 ].copy( face.normal );
|
|
vertexNormals[ 2 ].copy( face.normal );
|
|
|
|
} else {
|
|
|
|
vertexNormals[ 0 ] = face.normal.clone();
|
|
vertexNormals[ 1 ] = face.normal.clone();
|
|
vertexNormals[ 2 ] = face.normal.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.faces.length > 0 ) {
|
|
|
|
this.normalsNeedUpdate = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeMorphNormals: function () {
|
|
|
|
var i, il, f, fl, face;
|
|
|
|
// save original normals
|
|
// - create temp variables on first access
|
|
// otherwise just copy (for faster repeated calls)
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
if ( ! face.__originalFaceNormal ) {
|
|
|
|
face.__originalFaceNormal = face.normal.clone();
|
|
|
|
} else {
|
|
|
|
face.__originalFaceNormal.copy( face.normal );
|
|
|
|
}
|
|
|
|
if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
|
|
|
|
for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
|
|
|
|
if ( ! face.__originalVertexNormals[ i ] ) {
|
|
|
|
face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
|
|
|
|
} else {
|
|
|
|
face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// use temp geometry to compute face and vertex normals for each morph
|
|
|
|
var tmpGeo = new Geometry();
|
|
tmpGeo.faces = this.faces;
|
|
|
|
for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
|
|
|
|
// create on first access
|
|
|
|
if ( ! this.morphNormals[ i ] ) {
|
|
|
|
this.morphNormals[ i ] = {};
|
|
this.morphNormals[ i ].faceNormals = [];
|
|
this.morphNormals[ i ].vertexNormals = [];
|
|
|
|
var dstNormalsFace = this.morphNormals[ i ].faceNormals;
|
|
var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
|
|
|
|
var faceNormal, vertexNormals;
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
faceNormal = new Vector3();
|
|
vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
|
|
|
|
dstNormalsFace.push( faceNormal );
|
|
dstNormalsVertex.push( vertexNormals );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var morphNormals = this.morphNormals[ i ];
|
|
|
|
// set vertices to morph target
|
|
|
|
tmpGeo.vertices = this.morphTargets[ i ].vertices;
|
|
|
|
// compute morph normals
|
|
|
|
tmpGeo.computeFaceNormals();
|
|
tmpGeo.computeVertexNormals();
|
|
|
|
// store morph normals
|
|
|
|
var faceNormal, vertexNormals;
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
faceNormal = morphNormals.faceNormals[ f ];
|
|
vertexNormals = morphNormals.vertexNormals[ f ];
|
|
|
|
faceNormal.copy( face.normal );
|
|
|
|
vertexNormals.a.copy( face.vertexNormals[ 0 ] );
|
|
vertexNormals.b.copy( face.vertexNormals[ 1 ] );
|
|
vertexNormals.c.copy( face.vertexNormals[ 2 ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// restore original normals
|
|
|
|
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
|
|
|
|
face = this.faces[ f ];
|
|
|
|
face.normal = face.__originalFaceNormal;
|
|
face.vertexNormals = face.__originalVertexNormals;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeLineDistances: function () {
|
|
|
|
var d = 0;
|
|
var vertices = this.vertices;
|
|
|
|
for ( var i = 0, il = vertices.length; i < il; i ++ ) {
|
|
|
|
if ( i > 0 ) {
|
|
|
|
d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
|
|
|
|
}
|
|
|
|
this.lineDistances[ i ] = d;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeBoundingBox: function () {
|
|
|
|
if ( this.boundingBox === null ) {
|
|
|
|
this.boundingBox = new Box3();
|
|
|
|
}
|
|
|
|
this.boundingBox.setFromPoints( this.vertices );
|
|
|
|
},
|
|
|
|
computeBoundingSphere: function () {
|
|
|
|
if ( this.boundingSphere === null ) {
|
|
|
|
this.boundingSphere = new Sphere();
|
|
|
|
}
|
|
|
|
this.boundingSphere.setFromPoints( this.vertices );
|
|
|
|
},
|
|
|
|
merge: function ( geometry, matrix, materialIndexOffset ) {
|
|
|
|
if ( ( geometry && geometry.isGeometry ) === false ) {
|
|
|
|
console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
|
|
return;
|
|
|
|
}
|
|
|
|
var normalMatrix,
|
|
vertexOffset = this.vertices.length,
|
|
vertices1 = this.vertices,
|
|
vertices2 = geometry.vertices,
|
|
faces1 = this.faces,
|
|
faces2 = geometry.faces,
|
|
uvs1 = this.faceVertexUvs[ 0 ],
|
|
uvs2 = geometry.faceVertexUvs[ 0 ],
|
|
colors1 = this.colors,
|
|
colors2 = geometry.colors;
|
|
|
|
if ( materialIndexOffset === undefined ) materialIndexOffset = 0;
|
|
|
|
if ( matrix !== undefined ) {
|
|
|
|
normalMatrix = new Matrix3().getNormalMatrix( matrix );
|
|
|
|
}
|
|
|
|
// vertices
|
|
|
|
for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
|
|
|
|
var vertex = vertices2[ i ];
|
|
|
|
var vertexCopy = vertex.clone();
|
|
|
|
if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
|
|
|
|
vertices1.push( vertexCopy );
|
|
|
|
}
|
|
|
|
// colors
|
|
|
|
for ( var i = 0, il = colors2.length; i < il; i ++ ) {
|
|
|
|
colors1.push( colors2[ i ].clone() );
|
|
|
|
}
|
|
|
|
// faces
|
|
|
|
for ( i = 0, il = faces2.length; i < il; i ++ ) {
|
|
|
|
var face = faces2[ i ], faceCopy, normal, color,
|
|
faceVertexNormals = face.vertexNormals,
|
|
faceVertexColors = face.vertexColors;
|
|
|
|
faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
|
|
faceCopy.normal.copy( face.normal );
|
|
|
|
if ( normalMatrix !== undefined ) {
|
|
|
|
faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
|
|
|
|
}
|
|
|
|
for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
|
|
|
|
normal = faceVertexNormals[ j ].clone();
|
|
|
|
if ( normalMatrix !== undefined ) {
|
|
|
|
normal.applyMatrix3( normalMatrix ).normalize();
|
|
|
|
}
|
|
|
|
faceCopy.vertexNormals.push( normal );
|
|
|
|
}
|
|
|
|
faceCopy.color.copy( face.color );
|
|
|
|
for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
|
|
|
|
color = faceVertexColors[ j ];
|
|
faceCopy.vertexColors.push( color.clone() );
|
|
|
|
}
|
|
|
|
faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
|
|
|
|
faces1.push( faceCopy );
|
|
|
|
}
|
|
|
|
// uvs
|
|
|
|
for ( i = 0, il = uvs2.length; i < il; i ++ ) {
|
|
|
|
var uv = uvs2[ i ], uvCopy = [];
|
|
|
|
if ( uv === undefined ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
|
|
|
|
uvCopy.push( uv[ j ].clone() );
|
|
|
|
}
|
|
|
|
uvs1.push( uvCopy );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mergeMesh: function ( mesh ) {
|
|
|
|
if ( ( mesh && mesh.isMesh ) === false ) {
|
|
|
|
console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
|
|
return;
|
|
|
|
}
|
|
|
|
mesh.matrixAutoUpdate && mesh.updateMatrix();
|
|
|
|
this.merge( mesh.geometry, mesh.matrix );
|
|
|
|
},
|
|
|
|
/*
|
|
* Checks for duplicate vertices with hashmap.
|
|
* Duplicated vertices are removed
|
|
* and faces' vertices are updated.
|
|
*/
|
|
|
|
mergeVertices: function () {
|
|
|
|
var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
|
|
var unique = [], changes = [];
|
|
|
|
var v, key;
|
|
var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001
|
|
var precision = Math.pow( 10, precisionPoints );
|
|
var i, il, face;
|
|
var indices, j, jl;
|
|
|
|
for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
|
|
|
|
v = this.vertices[ i ];
|
|
key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
|
|
|
|
if ( verticesMap[ key ] === undefined ) {
|
|
|
|
verticesMap[ key ] = i;
|
|
unique.push( this.vertices[ i ] );
|
|
changes[ i ] = unique.length - 1;
|
|
|
|
} else {
|
|
|
|
//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
|
|
changes[ i ] = changes[ verticesMap[ key ] ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// if faces are completely degenerate after merging vertices, we
|
|
// have to remove them from the geometry.
|
|
var faceIndicesToRemove = [];
|
|
|
|
for ( i = 0, il = this.faces.length; i < il; i ++ ) {
|
|
|
|
face = this.faces[ i ];
|
|
|
|
face.a = changes[ face.a ];
|
|
face.b = changes[ face.b ];
|
|
face.c = changes[ face.c ];
|
|
|
|
indices = [ face.a, face.b, face.c ];
|
|
|
|
// if any duplicate vertices are found in a Face3
|
|
// we have to remove the face as nothing can be saved
|
|
for ( var n = 0; n < 3; n ++ ) {
|
|
|
|
if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
|
|
|
|
faceIndicesToRemove.push( i );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
|
|
|
|
var idx = faceIndicesToRemove[ i ];
|
|
|
|
this.faces.splice( idx, 1 );
|
|
|
|
for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
|
|
|
|
this.faceVertexUvs[ j ].splice( idx, 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Use unique set of vertices
|
|
|
|
var diff = this.vertices.length - unique.length;
|
|
this.vertices = unique;
|
|
return diff;
|
|
|
|
},
|
|
|
|
sortFacesByMaterialIndex: function () {
|
|
|
|
var faces = this.faces;
|
|
var length = faces.length;
|
|
|
|
// tag faces
|
|
|
|
for ( var i = 0; i < length; i ++ ) {
|
|
|
|
faces[ i ]._id = i;
|
|
|
|
}
|
|
|
|
// sort faces
|
|
|
|
function materialIndexSort( a, b ) {
|
|
|
|
return a.materialIndex - b.materialIndex;
|
|
|
|
}
|
|
|
|
faces.sort( materialIndexSort );
|
|
|
|
// sort uvs
|
|
|
|
var uvs1 = this.faceVertexUvs[ 0 ];
|
|
var uvs2 = this.faceVertexUvs[ 1 ];
|
|
|
|
var newUvs1, newUvs2;
|
|
|
|
if ( uvs1 && uvs1.length === length ) newUvs1 = [];
|
|
if ( uvs2 && uvs2.length === length ) newUvs2 = [];
|
|
|
|
for ( var i = 0; i < length; i ++ ) {
|
|
|
|
var id = faces[ i ]._id;
|
|
|
|
if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
|
|
if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
|
|
|
|
}
|
|
|
|
if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
|
|
if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
|
|
|
|
},
|
|
|
|
toJSON: function () {
|
|
|
|
var data = {
|
|
metadata: {
|
|
version: 4.5,
|
|
type: 'Geometry',
|
|
generator: 'Geometry.toJSON'
|
|
}
|
|
};
|
|
|
|
// standard Geometry serialization
|
|
|
|
data.uuid = this.uuid;
|
|
data.type = this.type;
|
|
if ( this.name !== '' ) data.name = this.name;
|
|
|
|
if ( this.parameters !== undefined ) {
|
|
|
|
var parameters = this.parameters;
|
|
|
|
for ( var key in parameters ) {
|
|
|
|
if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
var vertices = [];
|
|
|
|
for ( var i = 0; i < this.vertices.length; i ++ ) {
|
|
|
|
var vertex = this.vertices[ i ];
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
var faces = [];
|
|
var normals = [];
|
|
var normalsHash = {};
|
|
var colors = [];
|
|
var colorsHash = {};
|
|
var uvs = [];
|
|
var uvsHash = {};
|
|
|
|
for ( var i = 0; i < this.faces.length; i ++ ) {
|
|
|
|
var face = this.faces[ i ];
|
|
|
|
var hasMaterial = true;
|
|
var hasFaceUv = false; // deprecated
|
|
var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
|
|
var hasFaceNormal = face.normal.length() > 0;
|
|
var hasFaceVertexNormal = face.vertexNormals.length > 0;
|
|
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
|
|
var hasFaceVertexColor = face.vertexColors.length > 0;
|
|
|
|
var faceType = 0;
|
|
|
|
faceType = setBit( faceType, 0, 0 ); // isQuad
|
|
faceType = setBit( faceType, 1, hasMaterial );
|
|
faceType = setBit( faceType, 2, hasFaceUv );
|
|
faceType = setBit( faceType, 3, hasFaceVertexUv );
|
|
faceType = setBit( faceType, 4, hasFaceNormal );
|
|
faceType = setBit( faceType, 5, hasFaceVertexNormal );
|
|
faceType = setBit( faceType, 6, hasFaceColor );
|
|
faceType = setBit( faceType, 7, hasFaceVertexColor );
|
|
|
|
faces.push( faceType );
|
|
faces.push( face.a, face.b, face.c );
|
|
faces.push( face.materialIndex );
|
|
|
|
if ( hasFaceVertexUv ) {
|
|
|
|
var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
|
|
|
|
faces.push(
|
|
getUvIndex( faceVertexUvs[ 0 ] ),
|
|
getUvIndex( faceVertexUvs[ 1 ] ),
|
|
getUvIndex( faceVertexUvs[ 2 ] )
|
|
);
|
|
|
|
}
|
|
|
|
if ( hasFaceNormal ) {
|
|
|
|
faces.push( getNormalIndex( face.normal ) );
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexNormal ) {
|
|
|
|
var vertexNormals = face.vertexNormals;
|
|
|
|
faces.push(
|
|
getNormalIndex( vertexNormals[ 0 ] ),
|
|
getNormalIndex( vertexNormals[ 1 ] ),
|
|
getNormalIndex( vertexNormals[ 2 ] )
|
|
);
|
|
|
|
}
|
|
|
|
if ( hasFaceColor ) {
|
|
|
|
faces.push( getColorIndex( face.color ) );
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexColor ) {
|
|
|
|
var vertexColors = face.vertexColors;
|
|
|
|
faces.push(
|
|
getColorIndex( vertexColors[ 0 ] ),
|
|
getColorIndex( vertexColors[ 1 ] ),
|
|
getColorIndex( vertexColors[ 2 ] )
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setBit( value, position, enabled ) {
|
|
|
|
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
|
|
|
|
}
|
|
|
|
function getNormalIndex( normal ) {
|
|
|
|
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
|
|
|
|
if ( normalsHash[ hash ] !== undefined ) {
|
|
|
|
return normalsHash[ hash ];
|
|
|
|
}
|
|
|
|
normalsHash[ hash ] = normals.length / 3;
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
return normalsHash[ hash ];
|
|
|
|
}
|
|
|
|
function getColorIndex( color ) {
|
|
|
|
var hash = color.r.toString() + color.g.toString() + color.b.toString();
|
|
|
|
if ( colorsHash[ hash ] !== undefined ) {
|
|
|
|
return colorsHash[ hash ];
|
|
|
|
}
|
|
|
|
colorsHash[ hash ] = colors.length;
|
|
colors.push( color.getHex() );
|
|
|
|
return colorsHash[ hash ];
|
|
|
|
}
|
|
|
|
function getUvIndex( uv ) {
|
|
|
|
var hash = uv.x.toString() + uv.y.toString();
|
|
|
|
if ( uvsHash[ hash ] !== undefined ) {
|
|
|
|
return uvsHash[ hash ];
|
|
|
|
}
|
|
|
|
uvsHash[ hash ] = uvs.length / 2;
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
return uvsHash[ hash ];
|
|
|
|
}
|
|
|
|
data.data = {};
|
|
|
|
data.data.vertices = vertices;
|
|
data.data.normals = normals;
|
|
if ( colors.length > 0 ) data.data.colors = colors;
|
|
if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility
|
|
data.data.faces = faces;
|
|
|
|
return data;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
/*
|
|
// Handle primitives
|
|
|
|
var parameters = this.parameters;
|
|
|
|
if ( parameters !== undefined ) {
|
|
|
|
var values = [];
|
|
|
|
for ( var key in parameters ) {
|
|
|
|
values.push( parameters[ key ] );
|
|
|
|
}
|
|
|
|
var geometry = Object.create( this.constructor.prototype );
|
|
this.constructor.apply( geometry, values );
|
|
return geometry;
|
|
|
|
}
|
|
|
|
return new this.constructor().copy( this );
|
|
*/
|
|
|
|
return new Geometry().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
var i, il, j, jl, k, kl;
|
|
|
|
// reset
|
|
|
|
this.vertices = [];
|
|
this.colors = [];
|
|
this.faces = [];
|
|
this.faceVertexUvs = [[]];
|
|
this.morphTargets = [];
|
|
this.morphNormals = [];
|
|
this.skinWeights = [];
|
|
this.skinIndices = [];
|
|
this.lineDistances = [];
|
|
this.boundingBox = null;
|
|
this.boundingSphere = null;
|
|
|
|
// name
|
|
|
|
this.name = source.name;
|
|
|
|
// vertices
|
|
|
|
var vertices = source.vertices;
|
|
|
|
for ( i = 0, il = vertices.length; i < il; i ++ ) {
|
|
|
|
this.vertices.push( vertices[ i ].clone() );
|
|
|
|
}
|
|
|
|
// colors
|
|
|
|
var colors = source.colors;
|
|
|
|
for ( i = 0, il = colors.length; i < il; i ++ ) {
|
|
|
|
this.colors.push( colors[ i ].clone() );
|
|
|
|
}
|
|
|
|
// faces
|
|
|
|
var faces = source.faces;
|
|
|
|
for ( i = 0, il = faces.length; i < il; i ++ ) {
|
|
|
|
this.faces.push( faces[ i ].clone() );
|
|
|
|
}
|
|
|
|
// face vertex uvs
|
|
|
|
for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
|
|
|
|
var faceVertexUvs = source.faceVertexUvs[ i ];
|
|
|
|
if ( this.faceVertexUvs[ i ] === undefined ) {
|
|
|
|
this.faceVertexUvs[ i ] = [];
|
|
|
|
}
|
|
|
|
for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
|
|
|
|
var uvs = faceVertexUvs[ j ], uvsCopy = [];
|
|
|
|
for ( k = 0, kl = uvs.length; k < kl; k ++ ) {
|
|
|
|
var uv = uvs[ k ];
|
|
|
|
uvsCopy.push( uv.clone() );
|
|
|
|
}
|
|
|
|
this.faceVertexUvs[ i ].push( uvsCopy );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// morph targets
|
|
|
|
var morphTargets = source.morphTargets;
|
|
|
|
for ( i = 0, il = morphTargets.length; i < il; i ++ ) {
|
|
|
|
var morphTarget = {};
|
|
morphTarget.name = morphTargets[ i ].name;
|
|
|
|
// vertices
|
|
|
|
if ( morphTargets[ i ].vertices !== undefined ) {
|
|
|
|
morphTarget.vertices = [];
|
|
|
|
for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {
|
|
|
|
morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// normals
|
|
|
|
if ( morphTargets[ i ].normals !== undefined ) {
|
|
|
|
morphTarget.normals = [];
|
|
|
|
for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {
|
|
|
|
morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.morphTargets.push( morphTarget );
|
|
|
|
}
|
|
|
|
// morph normals
|
|
|
|
var morphNormals = source.morphNormals;
|
|
|
|
for ( i = 0, il = morphNormals.length; i < il; i ++ ) {
|
|
|
|
var morphNormal = {};
|
|
|
|
// vertex normals
|
|
|
|
if ( morphNormals[ i ].vertexNormals !== undefined ) {
|
|
|
|
morphNormal.vertexNormals = [];
|
|
|
|
for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {
|
|
|
|
var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];
|
|
var destVertexNormal = {};
|
|
|
|
destVertexNormal.a = srcVertexNormal.a.clone();
|
|
destVertexNormal.b = srcVertexNormal.b.clone();
|
|
destVertexNormal.c = srcVertexNormal.c.clone();
|
|
|
|
morphNormal.vertexNormals.push( destVertexNormal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// face normals
|
|
|
|
if ( morphNormals[ i ].faceNormals !== undefined ) {
|
|
|
|
morphNormal.faceNormals = [];
|
|
|
|
for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {
|
|
|
|
morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.morphNormals.push( morphNormal );
|
|
|
|
}
|
|
|
|
// skin weights
|
|
|
|
var skinWeights = source.skinWeights;
|
|
|
|
for ( i = 0, il = skinWeights.length; i < il; i ++ ) {
|
|
|
|
this.skinWeights.push( skinWeights[ i ].clone() );
|
|
|
|
}
|
|
|
|
// skin indices
|
|
|
|
var skinIndices = source.skinIndices;
|
|
|
|
for ( i = 0, il = skinIndices.length; i < il; i ++ ) {
|
|
|
|
this.skinIndices.push( skinIndices[ i ].clone() );
|
|
|
|
}
|
|
|
|
// line distances
|
|
|
|
var lineDistances = source.lineDistances;
|
|
|
|
for ( i = 0, il = lineDistances.length; i < il; i ++ ) {
|
|
|
|
this.lineDistances.push( lineDistances[ i ] );
|
|
|
|
}
|
|
|
|
// bounding box
|
|
|
|
var boundingBox = source.boundingBox;
|
|
|
|
if ( boundingBox !== null ) {
|
|
|
|
this.boundingBox = boundingBox.clone();
|
|
|
|
}
|
|
|
|
// bounding sphere
|
|
|
|
var boundingSphere = source.boundingSphere;
|
|
|
|
if ( boundingSphere !== null ) {
|
|
|
|
this.boundingSphere = boundingSphere.clone();
|
|
|
|
}
|
|
|
|
// update flags
|
|
|
|
this.elementsNeedUpdate = source.elementsNeedUpdate;
|
|
this.verticesNeedUpdate = source.verticesNeedUpdate;
|
|
this.uvsNeedUpdate = source.uvsNeedUpdate;
|
|
this.normalsNeedUpdate = source.normalsNeedUpdate;
|
|
this.colorsNeedUpdate = source.colorsNeedUpdate;
|
|
this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
|
|
this.groupsNeedUpdate = source.groupsNeedUpdate;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dispose: function () {
|
|
|
|
this.dispatchEvent( { type: 'dispose' } );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function BufferGeometry() {
|
|
|
|
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.name = '';
|
|
this.type = 'BufferGeometry';
|
|
|
|
this.index = null;
|
|
this.attributes = {};
|
|
|
|
this.morphAttributes = {};
|
|
|
|
this.groups = [];
|
|
|
|
this.boundingBox = null;
|
|
this.boundingSphere = null;
|
|
|
|
this.drawRange = { start: 0, count: Infinity };
|
|
|
|
}
|
|
|
|
BufferGeometry.MaxIndex = 65535;
|
|
|
|
Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, {
|
|
|
|
isBufferGeometry: true,
|
|
|
|
getIndex: function () {
|
|
|
|
return this.index;
|
|
|
|
},
|
|
|
|
setIndex: function ( index ) {
|
|
|
|
if ( Array.isArray( index ) ) {
|
|
|
|
this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
|
|
|
|
} else {
|
|
|
|
this.index = index;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
addAttribute: function ( name, attribute ) {
|
|
|
|
if ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
|
|
|
|
this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( name === 'index' ) {
|
|
|
|
console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
|
|
this.setIndex( attribute );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.attributes[ name ] = attribute;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getAttribute: function ( name ) {
|
|
|
|
return this.attributes[ name ];
|
|
|
|
},
|
|
|
|
removeAttribute: function ( name ) {
|
|
|
|
delete this.attributes[ name ];
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addGroup: function ( start, count, materialIndex ) {
|
|
|
|
this.groups.push( {
|
|
|
|
start: start,
|
|
count: count,
|
|
materialIndex: materialIndex !== undefined ? materialIndex : 0
|
|
|
|
} );
|
|
|
|
},
|
|
|
|
clearGroups: function () {
|
|
|
|
this.groups = [];
|
|
|
|
},
|
|
|
|
setDrawRange: function ( start, count ) {
|
|
|
|
this.drawRange.start = start;
|
|
this.drawRange.count = count;
|
|
|
|
},
|
|
|
|
applyMatrix: function ( matrix ) {
|
|
|
|
var position = this.attributes.position;
|
|
|
|
if ( position !== undefined ) {
|
|
|
|
matrix.applyToBufferAttribute( position );
|
|
position.needsUpdate = true;
|
|
|
|
}
|
|
|
|
var normal = this.attributes.normal;
|
|
|
|
if ( normal !== undefined ) {
|
|
|
|
var normalMatrix = new Matrix3().getNormalMatrix( matrix );
|
|
|
|
normalMatrix.applyToBufferAttribute( normal );
|
|
normal.needsUpdate = true;
|
|
|
|
}
|
|
|
|
if ( this.boundingBox !== null ) {
|
|
|
|
this.computeBoundingBox();
|
|
|
|
}
|
|
|
|
if ( this.boundingSphere !== null ) {
|
|
|
|
this.computeBoundingSphere();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
rotateX: function () {
|
|
|
|
// rotate geometry around world x-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateX( angle ) {
|
|
|
|
m1.makeRotationX( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateY: function () {
|
|
|
|
// rotate geometry around world y-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateY( angle ) {
|
|
|
|
m1.makeRotationY( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
rotateZ: function () {
|
|
|
|
// rotate geometry around world z-axis
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function rotateZ( angle ) {
|
|
|
|
m1.makeRotationZ( angle );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
translate: function () {
|
|
|
|
// translate geometry
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function translate( x, y, z ) {
|
|
|
|
m1.makeTranslation( x, y, z );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
scale: function () {
|
|
|
|
// scale geometry
|
|
|
|
var m1 = new Matrix4();
|
|
|
|
return function scale( x, y, z ) {
|
|
|
|
m1.makeScale( x, y, z );
|
|
|
|
this.applyMatrix( m1 );
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
lookAt: function () {
|
|
|
|
var obj = new Object3D();
|
|
|
|
return function lookAt( vector ) {
|
|
|
|
obj.lookAt( vector );
|
|
|
|
obj.updateMatrix();
|
|
|
|
this.applyMatrix( obj.matrix );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
center: function () {
|
|
|
|
this.computeBoundingBox();
|
|
|
|
var offset = this.boundingBox.getCenter().negate();
|
|
|
|
this.translate( offset.x, offset.y, offset.z );
|
|
|
|
return offset;
|
|
|
|
},
|
|
|
|
setFromObject: function ( object ) {
|
|
|
|
// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
|
|
|
|
var geometry = object.geometry;
|
|
|
|
if ( object.isPoints || object.isLine ) {
|
|
|
|
var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
|
|
var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
|
|
|
|
this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
|
|
this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
|
|
|
|
if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
|
|
|
|
var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
|
|
|
|
this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
|
|
|
|
}
|
|
|
|
if ( geometry.boundingSphere !== null ) {
|
|
|
|
this.boundingSphere = geometry.boundingSphere.clone();
|
|
|
|
}
|
|
|
|
if ( geometry.boundingBox !== null ) {
|
|
|
|
this.boundingBox = geometry.boundingBox.clone();
|
|
|
|
}
|
|
|
|
} else if ( object.isMesh ) {
|
|
|
|
if ( geometry && geometry.isGeometry ) {
|
|
|
|
this.fromGeometry( geometry );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
updateFromObject: function ( object ) {
|
|
|
|
var geometry = object.geometry;
|
|
|
|
if ( object.isMesh ) {
|
|
|
|
var direct = geometry.__directGeometry;
|
|
|
|
if ( geometry.elementsNeedUpdate === true ) {
|
|
|
|
direct = undefined;
|
|
geometry.elementsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( direct === undefined ) {
|
|
|
|
return this.fromGeometry( geometry );
|
|
|
|
}
|
|
|
|
direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
|
|
direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
|
|
direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
|
|
direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
|
|
direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
|
|
|
|
geometry.verticesNeedUpdate = false;
|
|
geometry.normalsNeedUpdate = false;
|
|
geometry.colorsNeedUpdate = false;
|
|
geometry.uvsNeedUpdate = false;
|
|
geometry.groupsNeedUpdate = false;
|
|
|
|
geometry = direct;
|
|
|
|
}
|
|
|
|
var attribute;
|
|
|
|
if ( geometry.verticesNeedUpdate === true ) {
|
|
|
|
attribute = this.attributes.position;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
attribute.copyVector3sArray( geometry.vertices );
|
|
attribute.needsUpdate = true;
|
|
|
|
}
|
|
|
|
geometry.verticesNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( geometry.normalsNeedUpdate === true ) {
|
|
|
|
attribute = this.attributes.normal;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
attribute.copyVector3sArray( geometry.normals );
|
|
attribute.needsUpdate = true;
|
|
|
|
}
|
|
|
|
geometry.normalsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( geometry.colorsNeedUpdate === true ) {
|
|
|
|
attribute = this.attributes.color;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
attribute.copyColorsArray( geometry.colors );
|
|
attribute.needsUpdate = true;
|
|
|
|
}
|
|
|
|
geometry.colorsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( geometry.uvsNeedUpdate ) {
|
|
|
|
attribute = this.attributes.uv;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
attribute.copyVector2sArray( geometry.uvs );
|
|
attribute.needsUpdate = true;
|
|
|
|
}
|
|
|
|
geometry.uvsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( geometry.lineDistancesNeedUpdate ) {
|
|
|
|
attribute = this.attributes.lineDistance;
|
|
|
|
if ( attribute !== undefined ) {
|
|
|
|
attribute.copyArray( geometry.lineDistances );
|
|
attribute.needsUpdate = true;
|
|
|
|
}
|
|
|
|
geometry.lineDistancesNeedUpdate = false;
|
|
|
|
}
|
|
|
|
if ( geometry.groupsNeedUpdate ) {
|
|
|
|
geometry.computeGroups( object.geometry );
|
|
this.groups = geometry.groups;
|
|
|
|
geometry.groupsNeedUpdate = false;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
fromGeometry: function ( geometry ) {
|
|
|
|
geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
|
|
|
|
return this.fromDirectGeometry( geometry.__directGeometry );
|
|
|
|
},
|
|
|
|
fromDirectGeometry: function ( geometry ) {
|
|
|
|
var positions = new Float32Array( geometry.vertices.length * 3 );
|
|
this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
|
|
|
|
if ( geometry.normals.length > 0 ) {
|
|
|
|
var normals = new Float32Array( geometry.normals.length * 3 );
|
|
this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
|
|
|
|
}
|
|
|
|
if ( geometry.colors.length > 0 ) {
|
|
|
|
var colors = new Float32Array( geometry.colors.length * 3 );
|
|
this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
|
|
|
|
}
|
|
|
|
if ( geometry.uvs.length > 0 ) {
|
|
|
|
var uvs = new Float32Array( geometry.uvs.length * 2 );
|
|
this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
|
|
|
|
}
|
|
|
|
if ( geometry.uvs2.length > 0 ) {
|
|
|
|
var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
|
|
this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
|
|
|
|
}
|
|
|
|
if ( geometry.indices.length > 0 ) {
|
|
|
|
var TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;
|
|
var indices = new TypeArray( geometry.indices.length * 3 );
|
|
this.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );
|
|
|
|
}
|
|
|
|
// groups
|
|
|
|
this.groups = geometry.groups;
|
|
|
|
// morphs
|
|
|
|
for ( var name in geometry.morphTargets ) {
|
|
|
|
var array = [];
|
|
var morphTargets = geometry.morphTargets[ name ];
|
|
|
|
for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
|
|
|
|
var morphTarget = morphTargets[ i ];
|
|
|
|
var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );
|
|
|
|
array.push( attribute.copyVector3sArray( morphTarget ) );
|
|
|
|
}
|
|
|
|
this.morphAttributes[ name ] = array;
|
|
|
|
}
|
|
|
|
// skinning
|
|
|
|
if ( geometry.skinIndices.length > 0 ) {
|
|
|
|
var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
|
|
this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
|
|
|
|
}
|
|
|
|
if ( geometry.skinWeights.length > 0 ) {
|
|
|
|
var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
|
|
this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
if ( geometry.boundingSphere !== null ) {
|
|
|
|
this.boundingSphere = geometry.boundingSphere.clone();
|
|
|
|
}
|
|
|
|
if ( geometry.boundingBox !== null ) {
|
|
|
|
this.boundingBox = geometry.boundingBox.clone();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
computeBoundingBox: function () {
|
|
|
|
if ( this.boundingBox === null ) {
|
|
|
|
this.boundingBox = new Box3();
|
|
|
|
}
|
|
|
|
var position = this.attributes.position;
|
|
|
|
if ( position !== undefined ) {
|
|
|
|
this.boundingBox.setFromBufferAttribute( position );
|
|
|
|
} else {
|
|
|
|
this.boundingBox.makeEmpty();
|
|
|
|
}
|
|
|
|
if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
|
|
|
|
console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computeBoundingSphere: function () {
|
|
|
|
var box = new Box3();
|
|
var vector = new Vector3();
|
|
|
|
return function computeBoundingSphere() {
|
|
|
|
if ( this.boundingSphere === null ) {
|
|
|
|
this.boundingSphere = new Sphere();
|
|
|
|
}
|
|
|
|
var position = this.attributes.position;
|
|
|
|
if ( position ) {
|
|
|
|
var center = this.boundingSphere.center;
|
|
|
|
box.setFromBufferAttribute( position );
|
|
box.getCenter( center );
|
|
|
|
// hoping to find a boundingSphere with a radius smaller than the
|
|
// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
|
|
|
|
var maxRadiusSq = 0;
|
|
|
|
for ( var i = 0, il = position.count; i < il; i ++ ) {
|
|
|
|
vector.x = position.getX( i );
|
|
vector.y = position.getY( i );
|
|
vector.z = position.getZ( i );
|
|
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
|
|
|
|
}
|
|
|
|
this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
|
|
|
|
if ( isNaN( this.boundingSphere.radius ) ) {
|
|
|
|
console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
computeFaceNormals: function () {
|
|
|
|
// backwards compatibility
|
|
|
|
},
|
|
|
|
computeVertexNormals: function () {
|
|
|
|
var index = this.index;
|
|
var attributes = this.attributes;
|
|
var groups = this.groups;
|
|
|
|
if ( attributes.position ) {
|
|
|
|
var positions = attributes.position.array;
|
|
|
|
if ( attributes.normal === undefined ) {
|
|
|
|
this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );
|
|
|
|
} else {
|
|
|
|
// reset existing normals to zero
|
|
|
|
var array = attributes.normal.array;
|
|
|
|
for ( var i = 0, il = array.length; i < il; i ++ ) {
|
|
|
|
array[ i ] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var normals = attributes.normal.array;
|
|
|
|
var vA, vB, vC;
|
|
var pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
|
|
var cb = new Vector3(), ab = new Vector3();
|
|
|
|
// indexed elements
|
|
|
|
if ( index ) {
|
|
|
|
var indices = index.array;
|
|
|
|
if ( groups.length === 0 ) {
|
|
|
|
this.addGroup( 0, indices.length );
|
|
|
|
}
|
|
|
|
for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
|
|
|
|
var group = groups[ j ];
|
|
|
|
var start = group.start;
|
|
var count = group.count;
|
|
|
|
for ( var i = start, il = start + count; i < il; i += 3 ) {
|
|
|
|
vA = indices[ i + 0 ] * 3;
|
|
vB = indices[ i + 1 ] * 3;
|
|
vC = indices[ i + 2 ] * 3;
|
|
|
|
pA.fromArray( positions, vA );
|
|
pB.fromArray( positions, vB );
|
|
pC.fromArray( positions, vC );
|
|
|
|
cb.subVectors( pC, pB );
|
|
ab.subVectors( pA, pB );
|
|
cb.cross( ab );
|
|
|
|
normals[ vA ] += cb.x;
|
|
normals[ vA + 1 ] += cb.y;
|
|
normals[ vA + 2 ] += cb.z;
|
|
|
|
normals[ vB ] += cb.x;
|
|
normals[ vB + 1 ] += cb.y;
|
|
normals[ vB + 2 ] += cb.z;
|
|
|
|
normals[ vC ] += cb.x;
|
|
normals[ vC + 1 ] += cb.y;
|
|
normals[ vC + 2 ] += cb.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// non-indexed elements (unconnected triangle soup)
|
|
|
|
for ( var i = 0, il = positions.length; i < il; i += 9 ) {
|
|
|
|
pA.fromArray( positions, i );
|
|
pB.fromArray( positions, i + 3 );
|
|
pC.fromArray( positions, i + 6 );
|
|
|
|
cb.subVectors( pC, pB );
|
|
ab.subVectors( pA, pB );
|
|
cb.cross( ab );
|
|
|
|
normals[ i ] = cb.x;
|
|
normals[ i + 1 ] = cb.y;
|
|
normals[ i + 2 ] = cb.z;
|
|
|
|
normals[ i + 3 ] = cb.x;
|
|
normals[ i + 4 ] = cb.y;
|
|
normals[ i + 5 ] = cb.z;
|
|
|
|
normals[ i + 6 ] = cb.x;
|
|
normals[ i + 7 ] = cb.y;
|
|
normals[ i + 8 ] = cb.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.normalizeNormals();
|
|
|
|
attributes.normal.needsUpdate = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
merge: function ( geometry, offset ) {
|
|
|
|
if ( ( geometry && geometry.isBufferGeometry ) === false ) {
|
|
|
|
console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
var attributes = this.attributes;
|
|
|
|
for ( var key in attributes ) {
|
|
|
|
if ( geometry.attributes[ key ] === undefined ) continue;
|
|
|
|
var attribute1 = attributes[ key ];
|
|
var attributeArray1 = attribute1.array;
|
|
|
|
var attribute2 = geometry.attributes[ key ];
|
|
var attributeArray2 = attribute2.array;
|
|
|
|
var attributeSize = attribute2.itemSize;
|
|
|
|
for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {
|
|
|
|
attributeArray1[ j ] = attributeArray2[ i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
normalizeNormals: function () {
|
|
|
|
var normals = this.attributes.normal;
|
|
|
|
var x, y, z, n;
|
|
|
|
for ( var i = 0, il = normals.count; i < il; i ++ ) {
|
|
|
|
x = normals.getX( i );
|
|
y = normals.getY( i );
|
|
z = normals.getZ( i );
|
|
|
|
n = 1.0 / Math.sqrt( x * x + y * y + z * z );
|
|
|
|
normals.setXYZ( i, x * n, y * n, z * n );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toNonIndexed: function () {
|
|
|
|
if ( this.index === null ) {
|
|
|
|
console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
|
|
return this;
|
|
|
|
}
|
|
|
|
var geometry2 = new BufferGeometry();
|
|
|
|
var indices = this.index.array;
|
|
var attributes = this.attributes;
|
|
|
|
for ( var name in attributes ) {
|
|
|
|
var attribute = attributes[ name ];
|
|
|
|
var array = attribute.array;
|
|
var itemSize = attribute.itemSize;
|
|
|
|
var array2 = new array.constructor( indices.length * itemSize );
|
|
|
|
var index = 0, index2 = 0;
|
|
|
|
for ( var i = 0, l = indices.length; i < l; i ++ ) {
|
|
|
|
index = indices[ i ] * itemSize;
|
|
|
|
for ( var j = 0; j < itemSize; j ++ ) {
|
|
|
|
array2[ index2 ++ ] = array[ index ++ ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );
|
|
|
|
}
|
|
|
|
return geometry2;
|
|
|
|
},
|
|
|
|
toJSON: function () {
|
|
|
|
var data = {
|
|
metadata: {
|
|
version: 4.5,
|
|
type: 'BufferGeometry',
|
|
generator: 'BufferGeometry.toJSON'
|
|
}
|
|
};
|
|
|
|
// standard BufferGeometry serialization
|
|
|
|
data.uuid = this.uuid;
|
|
data.type = this.type;
|
|
if ( this.name !== '' ) data.name = this.name;
|
|
|
|
if ( this.parameters !== undefined ) {
|
|
|
|
var parameters = this.parameters;
|
|
|
|
for ( var key in parameters ) {
|
|
|
|
if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
data.data = { attributes: {} };
|
|
|
|
var index = this.index;
|
|
|
|
if ( index !== null ) {
|
|
|
|
var array = Array.prototype.slice.call( index.array );
|
|
|
|
data.data.index = {
|
|
type: index.array.constructor.name,
|
|
array: array
|
|
};
|
|
|
|
}
|
|
|
|
var attributes = this.attributes;
|
|
|
|
for ( var key in attributes ) {
|
|
|
|
var attribute = attributes[ key ];
|
|
|
|
var array = Array.prototype.slice.call( attribute.array );
|
|
|
|
data.data.attributes[ key ] = {
|
|
itemSize: attribute.itemSize,
|
|
type: attribute.array.constructor.name,
|
|
array: array,
|
|
normalized: attribute.normalized
|
|
};
|
|
|
|
}
|
|
|
|
var groups = this.groups;
|
|
|
|
if ( groups.length > 0 ) {
|
|
|
|
data.data.groups = JSON.parse( JSON.stringify( groups ) );
|
|
|
|
}
|
|
|
|
var boundingSphere = this.boundingSphere;
|
|
|
|
if ( boundingSphere !== null ) {
|
|
|
|
data.data.boundingSphere = {
|
|
center: boundingSphere.center.toArray(),
|
|
radius: boundingSphere.radius
|
|
};
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
/*
|
|
// Handle primitives
|
|
|
|
var parameters = this.parameters;
|
|
|
|
if ( parameters !== undefined ) {
|
|
|
|
var values = [];
|
|
|
|
for ( var key in parameters ) {
|
|
|
|
values.push( parameters[ key ] );
|
|
|
|
}
|
|
|
|
var geometry = Object.create( this.constructor.prototype );
|
|
this.constructor.apply( geometry, values );
|
|
return geometry;
|
|
|
|
}
|
|
|
|
return new this.constructor().copy( this );
|
|
*/
|
|
|
|
return new BufferGeometry().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
var name, i, l;
|
|
|
|
// reset
|
|
|
|
this.index = null;
|
|
this.attributes = {};
|
|
this.morphAttributes = {};
|
|
this.groups = [];
|
|
this.boundingBox = null;
|
|
this.boundingSphere = null;
|
|
|
|
// name
|
|
|
|
this.name = source.name;
|
|
|
|
// index
|
|
|
|
var index = source.index;
|
|
|
|
if ( index !== null ) {
|
|
|
|
this.setIndex( index.clone() );
|
|
|
|
}
|
|
|
|
// attributes
|
|
|
|
var attributes = source.attributes;
|
|
|
|
for ( name in attributes ) {
|
|
|
|
var attribute = attributes[ name ];
|
|
this.addAttribute( name, attribute.clone() );
|
|
|
|
}
|
|
|
|
// morph attributes
|
|
|
|
var morphAttributes = source.morphAttributes;
|
|
|
|
for ( name in morphAttributes ) {
|
|
|
|
var array = [];
|
|
var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes
|
|
|
|
for ( i = 0, l = morphAttribute.length; i < l; i ++ ) {
|
|
|
|
array.push( morphAttribute[ i ].clone() );
|
|
|
|
}
|
|
|
|
this.morphAttributes[ name ] = array;
|
|
|
|
}
|
|
|
|
// groups
|
|
|
|
var groups = source.groups;
|
|
|
|
for ( i = 0, l = groups.length; i < l; i ++ ) {
|
|
|
|
var group = groups[ i ];
|
|
this.addGroup( group.start, group.count, group.materialIndex );
|
|
|
|
}
|
|
|
|
// bounding box
|
|
|
|
var boundingBox = source.boundingBox;
|
|
|
|
if ( boundingBox !== null ) {
|
|
|
|
this.boundingBox = boundingBox.clone();
|
|
|
|
}
|
|
|
|
// bounding sphere
|
|
|
|
var boundingSphere = source.boundingSphere;
|
|
|
|
if ( boundingSphere !== null ) {
|
|
|
|
this.boundingSphere = boundingSphere.clone();
|
|
|
|
}
|
|
|
|
// draw range
|
|
|
|
this.drawRange.start = source.drawRange.start;
|
|
this.drawRange.count = source.drawRange.count;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
dispose: function () {
|
|
|
|
this.dispatchEvent( { type: 'dispose' } );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author jonobr1 / http://jonobr1.com/
|
|
*/
|
|
|
|
function Mesh( geometry, material ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Mesh';
|
|
|
|
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
|
|
this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
|
|
|
|
this.drawMode = TrianglesDrawMode;
|
|
|
|
this.updateMorphTargets();
|
|
|
|
}
|
|
|
|
Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Mesh,
|
|
|
|
isMesh: true,
|
|
|
|
setDrawMode: function ( value ) {
|
|
|
|
this.drawMode = value;
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
Object3D.prototype.copy.call( this, source );
|
|
|
|
this.drawMode = source.drawMode;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
updateMorphTargets: function () {
|
|
|
|
var morphTargets = this.geometry.morphTargets;
|
|
|
|
if ( morphTargets !== undefined && morphTargets.length > 0 ) {
|
|
|
|
this.morphTargetInfluences = [];
|
|
this.morphTargetDictionary = {};
|
|
|
|
for ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {
|
|
|
|
this.morphTargetInfluences.push( 0 );
|
|
this.morphTargetDictionary[ morphTargets[ m ].name ] = m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
raycast: ( function () {
|
|
|
|
var inverseMatrix = new Matrix4();
|
|
var ray = new Ray();
|
|
var sphere = new Sphere();
|
|
|
|
var vA = new Vector3();
|
|
var vB = new Vector3();
|
|
var vC = new Vector3();
|
|
|
|
var tempA = new Vector3();
|
|
var tempB = new Vector3();
|
|
var tempC = new Vector3();
|
|
|
|
var uvA = new Vector2();
|
|
var uvB = new Vector2();
|
|
var uvC = new Vector2();
|
|
|
|
var barycoord = new Vector3();
|
|
|
|
var intersectionPoint = new Vector3();
|
|
var intersectionPointWorld = new Vector3();
|
|
|
|
function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
|
|
|
|
Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord );
|
|
|
|
uv1.multiplyScalar( barycoord.x );
|
|
uv2.multiplyScalar( barycoord.y );
|
|
uv3.multiplyScalar( barycoord.z );
|
|
|
|
uv1.add( uv2 ).add( uv3 );
|
|
|
|
return uv1.clone();
|
|
|
|
}
|
|
|
|
function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {
|
|
|
|
var intersect;
|
|
var material = object.material;
|
|
|
|
if ( material.side === BackSide ) {
|
|
|
|
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
|
|
|
|
} else {
|
|
|
|
intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
|
|
|
|
}
|
|
|
|
if ( intersect === null ) return null;
|
|
|
|
intersectionPointWorld.copy( point );
|
|
intersectionPointWorld.applyMatrix4( object.matrixWorld );
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) return null;
|
|
|
|
return {
|
|
distance: distance,
|
|
point: intersectionPointWorld.clone(),
|
|
object: object
|
|
};
|
|
|
|
}
|
|
|
|
function checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {
|
|
|
|
vA.fromBufferAttribute( position, a );
|
|
vB.fromBufferAttribute( position, b );
|
|
vC.fromBufferAttribute( position, c );
|
|
|
|
var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );
|
|
|
|
if ( intersection ) {
|
|
|
|
if ( uv ) {
|
|
|
|
uvA.fromBufferAttribute( uv, a );
|
|
uvB.fromBufferAttribute( uv, b );
|
|
uvC.fromBufferAttribute( uv, c );
|
|
|
|
intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
|
|
|
|
}
|
|
|
|
intersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );
|
|
intersection.faceIndex = a;
|
|
|
|
}
|
|
|
|
return intersection;
|
|
|
|
}
|
|
|
|
return function raycast( raycaster, intersects ) {
|
|
|
|
var geometry = this.geometry;
|
|
var material = this.material;
|
|
var matrixWorld = this.matrixWorld;
|
|
|
|
if ( material === undefined ) return;
|
|
|
|
// Checking boundingSphere distance to ray
|
|
|
|
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
|
|
|
sphere.copy( geometry.boundingSphere );
|
|
sphere.applyMatrix4( matrixWorld );
|
|
|
|
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
|
|
|
|
//
|
|
|
|
inverseMatrix.getInverse( matrixWorld );
|
|
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
|
|
|
|
// Check boundingBox before continuing
|
|
|
|
if ( geometry.boundingBox !== null ) {
|
|
|
|
if ( ray.intersectsBox( geometry.boundingBox ) === false ) return;
|
|
|
|
}
|
|
|
|
var intersection;
|
|
|
|
if ( geometry.isBufferGeometry ) {
|
|
|
|
var a, b, c;
|
|
var index = geometry.index;
|
|
var position = geometry.attributes.position;
|
|
var uv = geometry.attributes.uv;
|
|
var i, l;
|
|
|
|
if ( index !== null ) {
|
|
|
|
// indexed buffer geometry
|
|
|
|
for ( i = 0, l = index.count; i < l; i += 3 ) {
|
|
|
|
a = index.getX( i );
|
|
b = index.getX( i + 1 );
|
|
c = index.getX( i + 2 );
|
|
|
|
intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
|
|
|
|
if ( intersection ) {
|
|
|
|
intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics
|
|
intersects.push( intersection );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// non-indexed buffer geometry
|
|
|
|
for ( i = 0, l = position.count; i < l; i += 3 ) {
|
|
|
|
a = i;
|
|
b = i + 1;
|
|
c = i + 2;
|
|
|
|
intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
|
|
|
|
if ( intersection ) {
|
|
|
|
intersection.index = a; // triangle number in positions buffer semantics
|
|
intersects.push( intersection );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( geometry.isGeometry ) {
|
|
|
|
var fvA, fvB, fvC;
|
|
var isMultiMaterial = Array.isArray( material );
|
|
|
|
var vertices = geometry.vertices;
|
|
var faces = geometry.faces;
|
|
var uvs;
|
|
|
|
var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
|
|
if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
|
|
|
|
for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
|
|
|
|
var face = faces[ f ];
|
|
var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
|
|
|
|
if ( faceMaterial === undefined ) continue;
|
|
|
|
fvA = vertices[ face.a ];
|
|
fvB = vertices[ face.b ];
|
|
fvC = vertices[ face.c ];
|
|
|
|
if ( faceMaterial.morphTargets === true ) {
|
|
|
|
var morphTargets = geometry.morphTargets;
|
|
var morphInfluences = this.morphTargetInfluences;
|
|
|
|
vA.set( 0, 0, 0 );
|
|
vB.set( 0, 0, 0 );
|
|
vC.set( 0, 0, 0 );
|
|
|
|
for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
|
|
|
|
var influence = morphInfluences[ t ];
|
|
|
|
if ( influence === 0 ) continue;
|
|
|
|
var targets = morphTargets[ t ].vertices;
|
|
|
|
vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );
|
|
vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );
|
|
vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );
|
|
|
|
}
|
|
|
|
vA.add( fvA );
|
|
vB.add( fvB );
|
|
vC.add( fvC );
|
|
|
|
fvA = vA;
|
|
fvB = vB;
|
|
fvC = vC;
|
|
|
|
}
|
|
|
|
intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
|
|
|
|
if ( intersection ) {
|
|
|
|
if ( uvs && uvs[ f ] ) {
|
|
|
|
var uvs_f = uvs[ f ];
|
|
uvA.copy( uvs_f[ 0 ] );
|
|
uvB.copy( uvs_f[ 1 ] );
|
|
uvC.copy( uvs_f[ 2 ] );
|
|
|
|
intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );
|
|
|
|
}
|
|
|
|
intersection.face = face;
|
|
intersection.faceIndex = f;
|
|
intersects.push( intersection );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() ),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.geometry, this.material ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// BoxGeometry
|
|
|
|
function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'BoxGeometry';
|
|
|
|
this.parameters = {
|
|
width: width,
|
|
height: height,
|
|
depth: depth,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments,
|
|
depthSegments: depthSegments
|
|
};
|
|
|
|
this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
BoxGeometry.prototype = Object.create( Geometry.prototype );
|
|
BoxGeometry.prototype.constructor = BoxGeometry;
|
|
|
|
// BoxBufferGeometry
|
|
|
|
function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'BoxBufferGeometry';
|
|
|
|
this.parameters = {
|
|
width: width,
|
|
height: height,
|
|
depth: depth,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments,
|
|
depthSegments: depthSegments
|
|
};
|
|
|
|
var scope = this;
|
|
|
|
// segments
|
|
|
|
widthSegments = Math.floor( widthSegments ) || 1;
|
|
heightSegments = Math.floor( heightSegments ) || 1;
|
|
depthSegments = Math.floor( depthSegments ) || 1;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var numberOfVertices = 0;
|
|
var groupStart = 0;
|
|
|
|
// build each side of the box geometry
|
|
|
|
buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
|
|
buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
|
|
buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
|
|
buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
|
|
buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
|
|
buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
|
|
|
|
var segmentWidth = width / gridX;
|
|
var segmentHeight = height / gridY;
|
|
|
|
var widthHalf = width / 2;
|
|
var heightHalf = height / 2;
|
|
var depthHalf = depth / 2;
|
|
|
|
var gridX1 = gridX + 1;
|
|
var gridY1 = gridY + 1;
|
|
|
|
var vertexCounter = 0;
|
|
var groupCount = 0;
|
|
|
|
var ix, iy;
|
|
|
|
var vector = new Vector3();
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( iy = 0; iy < gridY1; iy ++ ) {
|
|
|
|
var y = iy * segmentHeight - heightHalf;
|
|
|
|
for ( ix = 0; ix < gridX1; ix ++ ) {
|
|
|
|
var x = ix * segmentWidth - widthHalf;
|
|
|
|
// set values to correct vector component
|
|
|
|
vector[ u ] = x * udir;
|
|
vector[ v ] = y * vdir;
|
|
vector[ w ] = depthHalf;
|
|
|
|
// now apply vector to vertex buffer
|
|
|
|
vertices.push( vector.x, vector.y, vector.z );
|
|
|
|
// set values to correct vector component
|
|
|
|
vector[ u ] = 0;
|
|
vector[ v ] = 0;
|
|
vector[ w ] = depth > 0 ? 1 : - 1;
|
|
|
|
// now apply vector to normal buffer
|
|
|
|
normals.push( vector.x, vector.y, vector.z );
|
|
|
|
// uvs
|
|
|
|
uvs.push( ix / gridX );
|
|
uvs.push( 1 - ( iy / gridY ) );
|
|
|
|
// counters
|
|
|
|
vertexCounter += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
// 1. you need three indices to draw a single face
|
|
// 2. a single segment consists of two faces
|
|
// 3. so we need to generate six (2*3) indices per segment
|
|
|
|
for ( iy = 0; iy < gridY; iy ++ ) {
|
|
|
|
for ( ix = 0; ix < gridX; ix ++ ) {
|
|
|
|
var a = numberOfVertices + ix + gridX1 * iy;
|
|
var b = numberOfVertices + ix + gridX1 * ( iy + 1 );
|
|
var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
|
|
var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
// increase counter
|
|
|
|
groupCount += 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// add a group to the geometry. this will ensure multi material support
|
|
|
|
scope.addGroup( groupStart, groupCount, materialIndex );
|
|
|
|
// calculate new start value for groups
|
|
|
|
groupStart += groupCount;
|
|
|
|
// update total number of vertices
|
|
|
|
numberOfVertices += vertexCounter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// PlaneGeometry
|
|
|
|
function PlaneGeometry( width, height, widthSegments, heightSegments ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'PlaneGeometry';
|
|
|
|
this.parameters = {
|
|
width: width,
|
|
height: height,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments
|
|
};
|
|
|
|
this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
PlaneGeometry.prototype = Object.create( Geometry.prototype );
|
|
PlaneGeometry.prototype.constructor = PlaneGeometry;
|
|
|
|
// PlaneBufferGeometry
|
|
|
|
function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'PlaneBufferGeometry';
|
|
|
|
this.parameters = {
|
|
width: width,
|
|
height: height,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments
|
|
};
|
|
|
|
var width_half = width / 2;
|
|
var height_half = height / 2;
|
|
|
|
var gridX = Math.floor( widthSegments ) || 1;
|
|
var gridY = Math.floor( heightSegments ) || 1;
|
|
|
|
var gridX1 = gridX + 1;
|
|
var gridY1 = gridY + 1;
|
|
|
|
var segment_width = width / gridX;
|
|
var segment_height = height / gridY;
|
|
|
|
var ix, iy;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( iy = 0; iy < gridY1; iy ++ ) {
|
|
|
|
var y = iy * segment_height - height_half;
|
|
|
|
for ( ix = 0; ix < gridX1; ix ++ ) {
|
|
|
|
var x = ix * segment_width - width_half;
|
|
|
|
vertices.push( x, - y, 0 );
|
|
|
|
normals.push( 0, 0, 1 );
|
|
|
|
uvs.push( ix / gridX );
|
|
uvs.push( 1 - ( iy / gridY ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
for ( iy = 0; iy < gridY; iy ++ ) {
|
|
|
|
for ( ix = 0; ix < gridX; ix ++ ) {
|
|
|
|
var a = ix + gridX1 * iy;
|
|
var b = ix + gridX1 * ( iy + 1 );
|
|
var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
|
|
var d = ( ix + 1 ) + gridX1 * iy;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function Camera() {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Camera';
|
|
|
|
this.matrixWorldInverse = new Matrix4();
|
|
this.projectionMatrix = new Matrix4();
|
|
|
|
}
|
|
|
|
Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Camera,
|
|
|
|
isCamera: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Object3D.prototype.copy.call( this, source );
|
|
|
|
this.matrixWorldInverse.copy( source.matrixWorldInverse );
|
|
this.projectionMatrix.copy( source.projectionMatrix );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getWorldDirection: function () {
|
|
|
|
var quaternion = new Quaternion();
|
|
|
|
return function getWorldDirection( optionalTarget ) {
|
|
|
|
var result = optionalTarget || new Vector3();
|
|
|
|
this.getWorldQuaternion( quaternion );
|
|
|
|
return result.set( 0, 0, - 1 ).applyQuaternion( quaternion );
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author greggman / http://games.greggman.com/
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* @author tschw
|
|
*/
|
|
|
|
function PerspectiveCamera( fov, aspect, near, far ) {
|
|
|
|
Camera.call( this );
|
|
|
|
this.type = 'PerspectiveCamera';
|
|
|
|
this.fov = fov !== undefined ? fov : 50;
|
|
this.zoom = 1;
|
|
|
|
this.near = near !== undefined ? near : 0.1;
|
|
this.far = far !== undefined ? far : 2000;
|
|
this.focus = 10;
|
|
|
|
this.aspect = aspect !== undefined ? aspect : 1;
|
|
this.view = null;
|
|
|
|
this.filmGauge = 35; // width of the film (default in millimeters)
|
|
this.filmOffset = 0; // horizontal film offset (same unit as gauge)
|
|
|
|
this.updateProjectionMatrix();
|
|
|
|
}
|
|
|
|
PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
|
|
|
|
constructor: PerspectiveCamera,
|
|
|
|
isPerspectiveCamera: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Camera.prototype.copy.call( this, source );
|
|
|
|
this.fov = source.fov;
|
|
this.zoom = source.zoom;
|
|
|
|
this.near = source.near;
|
|
this.far = source.far;
|
|
this.focus = source.focus;
|
|
|
|
this.aspect = source.aspect;
|
|
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
|
|
|
this.filmGauge = source.filmGauge;
|
|
this.filmOffset = source.filmOffset;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets the FOV by focal length in respect to the current .filmGauge.
|
|
*
|
|
* The default film gauge is 35, so that the focal length can be specified for
|
|
* a 35mm (full frame) camera.
|
|
*
|
|
* Values for focal length and film gauge must have the same unit.
|
|
*/
|
|
setFocalLength: function ( focalLength ) {
|
|
|
|
// see http://www.bobatkins.com/photography/technical/field_of_view.html
|
|
var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
|
|
|
|
this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
|
|
this.updateProjectionMatrix();
|
|
|
|
},
|
|
|
|
/**
|
|
* Calculates the focal length from the current .fov and .filmGauge.
|
|
*/
|
|
getFocalLength: function () {
|
|
|
|
var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );
|
|
|
|
return 0.5 * this.getFilmHeight() / vExtentSlope;
|
|
|
|
},
|
|
|
|
getEffectiveFOV: function () {
|
|
|
|
return _Math.RAD2DEG * 2 * Math.atan(
|
|
Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );
|
|
|
|
},
|
|
|
|
getFilmWidth: function () {
|
|
|
|
// film not completely covered in portrait format (aspect < 1)
|
|
return this.filmGauge * Math.min( this.aspect, 1 );
|
|
|
|
},
|
|
|
|
getFilmHeight: function () {
|
|
|
|
// film not completely covered in landscape format (aspect > 1)
|
|
return this.filmGauge / Math.max( this.aspect, 1 );
|
|
|
|
},
|
|
|
|
/**
|
|
* Sets an offset in a larger frustum. This is useful for multi-window or
|
|
* multi-monitor/multi-machine setups.
|
|
*
|
|
* For example, if you have 3x2 monitors and each monitor is 1920x1080 and
|
|
* the monitors are in grid like this
|
|
*
|
|
* +---+---+---+
|
|
* | A | B | C |
|
|
* +---+---+---+
|
|
* | D | E | F |
|
|
* +---+---+---+
|
|
*
|
|
* then for each monitor you would call it like this
|
|
*
|
|
* var w = 1920;
|
|
* var h = 1080;
|
|
* var fullWidth = w * 3;
|
|
* var fullHeight = h * 2;
|
|
*
|
|
* --A--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
|
|
* --B--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
|
|
* --C--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
|
|
* --D--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
|
|
* --E--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
|
|
* --F--
|
|
* camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
|
|
*
|
|
* Note there is no reason monitors have to be the same size or in a grid.
|
|
*/
|
|
setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
|
|
|
|
this.aspect = fullWidth / fullHeight;
|
|
|
|
this.view = {
|
|
fullWidth: fullWidth,
|
|
fullHeight: fullHeight,
|
|
offsetX: x,
|
|
offsetY: y,
|
|
width: width,
|
|
height: height
|
|
};
|
|
|
|
this.updateProjectionMatrix();
|
|
|
|
},
|
|
|
|
clearViewOffset: function () {
|
|
|
|
this.view = null;
|
|
this.updateProjectionMatrix();
|
|
|
|
},
|
|
|
|
updateProjectionMatrix: function () {
|
|
|
|
var near = this.near,
|
|
top = near * Math.tan(
|
|
_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,
|
|
height = 2 * top,
|
|
width = this.aspect * height,
|
|
left = - 0.5 * width,
|
|
view = this.view;
|
|
|
|
if ( view !== null ) {
|
|
|
|
var fullWidth = view.fullWidth,
|
|
fullHeight = view.fullHeight;
|
|
|
|
left += view.offsetX * width / fullWidth;
|
|
top -= view.offsetY * height / fullHeight;
|
|
width *= view.width / fullWidth;
|
|
height *= view.height / fullHeight;
|
|
|
|
}
|
|
|
|
var skew = this.filmOffset;
|
|
if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
|
|
|
|
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Object3D.prototype.toJSON.call( this, meta );
|
|
|
|
data.object.fov = this.fov;
|
|
data.object.zoom = this.zoom;
|
|
|
|
data.object.near = this.near;
|
|
data.object.far = this.far;
|
|
data.object.focus = this.focus;
|
|
|
|
data.object.aspect = this.aspect;
|
|
|
|
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
|
|
|
data.object.filmGauge = this.filmGauge;
|
|
data.object.filmOffset = this.filmOffset;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author arose / http://github.com/arose
|
|
*/
|
|
|
|
function OrthographicCamera( left, right, top, bottom, near, far ) {
|
|
|
|
Camera.call( this );
|
|
|
|
this.type = 'OrthographicCamera';
|
|
|
|
this.zoom = 1;
|
|
this.view = null;
|
|
|
|
this.left = left;
|
|
this.right = right;
|
|
this.top = top;
|
|
this.bottom = bottom;
|
|
|
|
this.near = ( near !== undefined ) ? near : 0.1;
|
|
this.far = ( far !== undefined ) ? far : 2000;
|
|
|
|
this.updateProjectionMatrix();
|
|
|
|
}
|
|
|
|
OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
|
|
|
|
constructor: OrthographicCamera,
|
|
|
|
isOrthographicCamera: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Camera.prototype.copy.call( this, source );
|
|
|
|
this.left = source.left;
|
|
this.right = source.right;
|
|
this.top = source.top;
|
|
this.bottom = source.bottom;
|
|
this.near = source.near;
|
|
this.far = source.far;
|
|
|
|
this.zoom = source.zoom;
|
|
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {
|
|
|
|
this.view = {
|
|
fullWidth: fullWidth,
|
|
fullHeight: fullHeight,
|
|
offsetX: x,
|
|
offsetY: y,
|
|
width: width,
|
|
height: height
|
|
};
|
|
|
|
this.updateProjectionMatrix();
|
|
|
|
},
|
|
|
|
clearViewOffset: function() {
|
|
|
|
this.view = null;
|
|
this.updateProjectionMatrix();
|
|
|
|
},
|
|
|
|
updateProjectionMatrix: function () {
|
|
|
|
var dx = ( this.right - this.left ) / ( 2 * this.zoom );
|
|
var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
|
|
var cx = ( this.right + this.left ) / 2;
|
|
var cy = ( this.top + this.bottom ) / 2;
|
|
|
|
var left = cx - dx;
|
|
var right = cx + dx;
|
|
var top = cy + dy;
|
|
var bottom = cy - dy;
|
|
|
|
if ( this.view !== null ) {
|
|
|
|
var zoomW = this.zoom / ( this.view.width / this.view.fullWidth );
|
|
var zoomH = this.zoom / ( this.view.height / this.view.fullHeight );
|
|
var scaleW = ( this.right - this.left ) / this.view.width;
|
|
var scaleH = ( this.top - this.bottom ) / this.view.height;
|
|
|
|
left += scaleW * ( this.view.offsetX / zoomW );
|
|
right = left + scaleW * ( this.view.width / zoomW );
|
|
top -= scaleH * ( this.view.offsetY / zoomH );
|
|
bottom = top - scaleH * ( this.view.height / zoomH );
|
|
|
|
}
|
|
|
|
this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Object3D.prototype.toJSON.call( this, meta );
|
|
|
|
data.object.zoom = this.zoom;
|
|
data.object.left = this.left;
|
|
data.object.right = this.right;
|
|
data.object.top = this.top;
|
|
data.object.bottom = this.bottom;
|
|
data.object.near = this.near;
|
|
data.object.far = this.far;
|
|
|
|
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLAttributes( gl ) {
|
|
|
|
var buffers = {};
|
|
|
|
function createBuffer( attribute, bufferType ) {
|
|
|
|
var array = attribute.array;
|
|
var usage = attribute.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;
|
|
|
|
var buffer = gl.createBuffer();
|
|
|
|
gl.bindBuffer( bufferType, buffer );
|
|
gl.bufferData( bufferType, array, usage );
|
|
|
|
attribute.onUploadCallback();
|
|
|
|
var type = gl.FLOAT;
|
|
|
|
if ( array instanceof Float32Array ) {
|
|
|
|
type = gl.FLOAT;
|
|
|
|
} else if ( array instanceof Float64Array ) {
|
|
|
|
console.warn( "Unsupported data buffer format: Float64Array" );
|
|
|
|
} else if ( array instanceof Uint16Array ) {
|
|
|
|
type = gl.UNSIGNED_SHORT;
|
|
|
|
} else if ( array instanceof Int16Array ) {
|
|
|
|
type = gl.SHORT;
|
|
|
|
} else if ( array instanceof Uint32Array ) {
|
|
|
|
type = gl.UNSIGNED_INT;
|
|
|
|
} else if ( array instanceof Int32Array ) {
|
|
|
|
type = gl.INT;
|
|
|
|
} else if ( array instanceof Int8Array ) {
|
|
|
|
type = gl.BYTE;
|
|
|
|
} else if ( array instanceof Uint8Array ) {
|
|
|
|
type = gl.UNSIGNED_BYTE;
|
|
|
|
}
|
|
|
|
return {
|
|
buffer: buffer,
|
|
type: type,
|
|
bytesPerElement: array.BYTES_PER_ELEMENT,
|
|
version: attribute.version
|
|
};
|
|
|
|
}
|
|
|
|
function updateBuffer( buffer, attribute, bufferType ) {
|
|
|
|
var array = attribute.array;
|
|
var updateRange = attribute.updateRange;
|
|
|
|
gl.bindBuffer( bufferType, buffer );
|
|
|
|
if ( attribute.dynamic === false ) {
|
|
|
|
gl.bufferData( bufferType, array, gl.STATIC_DRAW );
|
|
|
|
} else if ( updateRange.count === - 1 ) {
|
|
|
|
// Not using update ranges
|
|
|
|
gl.bufferSubData( bufferType, 0, array );
|
|
|
|
} else if ( updateRange.count === 0 ) {
|
|
|
|
console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );
|
|
|
|
} else {
|
|
|
|
gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
|
|
array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );
|
|
|
|
updateRange.count = 0; // reset range
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function get( attribute ) {
|
|
|
|
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
|
|
|
return buffers[ attribute.uuid ];
|
|
|
|
}
|
|
|
|
function remove( attribute ) {
|
|
|
|
var data = buffers[ attribute.uuid ];
|
|
|
|
if ( data ) {
|
|
|
|
gl.deleteBuffer( data.buffer );
|
|
|
|
delete buffers[ attribute.uuid ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function update( attribute, bufferType ) {
|
|
|
|
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
|
|
|
var data = buffers[ attribute.uuid ];
|
|
|
|
if ( data === undefined ) {
|
|
|
|
buffers[ attribute.uuid ] = createBuffer( attribute, bufferType );
|
|
|
|
} else if ( data.version < attribute.version ) {
|
|
|
|
updateBuffer( data.buffer, attribute, bufferType );
|
|
|
|
data.version = attribute.version;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
get: get,
|
|
remove: remove,
|
|
update: update
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function painterSortStable( a, b ) {
|
|
|
|
if ( a.renderOrder !== b.renderOrder ) {
|
|
|
|
return a.renderOrder - b.renderOrder;
|
|
|
|
} else if ( a.program && b.program && a.program !== b.program ) {
|
|
|
|
return a.program.id - b.program.id;
|
|
|
|
} else if ( a.material.id !== b.material.id ) {
|
|
|
|
return a.material.id - b.material.id;
|
|
|
|
} else if ( a.z !== b.z ) {
|
|
|
|
return a.z - b.z;
|
|
|
|
} else {
|
|
|
|
return a.id - b.id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function reversePainterSortStable( a, b ) {
|
|
|
|
if ( a.renderOrder !== b.renderOrder ) {
|
|
|
|
return a.renderOrder - b.renderOrder;
|
|
|
|
} if ( a.z !== b.z ) {
|
|
|
|
return b.z - a.z;
|
|
|
|
} else {
|
|
|
|
return a.id - b.id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function WebGLRenderList() {
|
|
|
|
var opaque = [];
|
|
var opaqueLastIndex = - 1;
|
|
|
|
var transparent = [];
|
|
var transparentLastIndex = - 1;
|
|
|
|
function init() {
|
|
|
|
opaqueLastIndex = - 1;
|
|
transparentLastIndex = - 1;
|
|
|
|
}
|
|
|
|
function push( object, geometry, material, z, group ) {
|
|
|
|
var array, index;
|
|
|
|
// allocate the next position in the appropriate array
|
|
|
|
if ( material.transparent ) {
|
|
|
|
array = transparent;
|
|
index = ++ transparentLastIndex;
|
|
|
|
} else {
|
|
|
|
array = opaque;
|
|
index = ++ opaqueLastIndex;
|
|
|
|
}
|
|
|
|
// recycle existing render item or grow the array
|
|
|
|
var renderItem = array[ index ];
|
|
|
|
if ( renderItem ) {
|
|
|
|
renderItem.id = object.id;
|
|
renderItem.object = object;
|
|
renderItem.geometry = geometry;
|
|
renderItem.material = material;
|
|
renderItem.program = material.program;
|
|
renderItem.renderOrder = object.renderOrder;
|
|
renderItem.z = z;
|
|
renderItem.group = group;
|
|
|
|
} else {
|
|
|
|
renderItem = {
|
|
id: object.id,
|
|
object: object,
|
|
geometry: geometry,
|
|
material: material,
|
|
program: material.program,
|
|
renderOrder: object.renderOrder,
|
|
z: z,
|
|
group: group
|
|
};
|
|
|
|
// assert( index === array.length );
|
|
array.push( renderItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function finish() {
|
|
|
|
opaque.length = opaqueLastIndex + 1;
|
|
transparent.length = transparentLastIndex + 1;
|
|
|
|
}
|
|
|
|
function sort() {
|
|
|
|
opaque.sort( painterSortStable );
|
|
transparent.sort( reversePainterSortStable );
|
|
|
|
}
|
|
|
|
return {
|
|
opaque: opaque,
|
|
transparent: transparent,
|
|
|
|
init: init,
|
|
push: push,
|
|
finish: finish,
|
|
|
|
sort: sort
|
|
};
|
|
|
|
}
|
|
|
|
function WebGLRenderLists() {
|
|
|
|
var lists = {};
|
|
|
|
function get( scene, camera ) {
|
|
|
|
var hash = scene.id + ',' + camera.id;
|
|
var list = lists[ hash ];
|
|
|
|
if ( list === undefined ) {
|
|
|
|
// console.log( 'THREE.WebGLRenderLists:', hash );
|
|
|
|
list = new WebGLRenderList();
|
|
lists[ hash ] = list;
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
function dispose() {
|
|
|
|
lists = {};
|
|
|
|
}
|
|
|
|
return {
|
|
get: get,
|
|
dispose: dispose
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {
|
|
|
|
var mode;
|
|
|
|
function setMode( value ) {
|
|
|
|
mode = value;
|
|
|
|
}
|
|
|
|
var type, size;
|
|
|
|
function setIndex( index ) {
|
|
|
|
if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
|
|
|
|
type = gl.UNSIGNED_INT;
|
|
size = 4;
|
|
|
|
} else if ( index.array instanceof Uint16Array ) {
|
|
|
|
type = gl.UNSIGNED_SHORT;
|
|
size = 2;
|
|
|
|
} else {
|
|
|
|
type = gl.UNSIGNED_BYTE;
|
|
size = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function render( start, count ) {
|
|
|
|
gl.drawElements( mode, count, type, start * size );
|
|
|
|
infoRender.calls ++;
|
|
infoRender.vertices += count;
|
|
|
|
if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
|
|
|
|
}
|
|
|
|
function renderInstances( geometry, start, count ) {
|
|
|
|
var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
if ( extension === null ) {
|
|
|
|
console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
return;
|
|
|
|
}
|
|
|
|
extension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );
|
|
|
|
infoRender.calls ++;
|
|
infoRender.vertices += count * geometry.maxInstancedCount;
|
|
|
|
if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
this.setMode = setMode;
|
|
this.setIndex = setIndex;
|
|
this.render = render;
|
|
this.renderInstances = renderInstances;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLBufferRenderer( gl, extensions, infoRender ) {
|
|
|
|
var mode;
|
|
|
|
function setMode( value ) {
|
|
|
|
mode = value;
|
|
|
|
}
|
|
|
|
function render( start, count ) {
|
|
|
|
gl.drawArrays( mode, start, count );
|
|
|
|
infoRender.calls ++;
|
|
infoRender.vertices += count;
|
|
|
|
if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
|
|
|
|
}
|
|
|
|
function renderInstances( geometry, start, count ) {
|
|
|
|
var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
if ( extension === null ) {
|
|
|
|
console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
return;
|
|
|
|
}
|
|
|
|
var position = geometry.attributes.position;
|
|
|
|
if ( position.isInterleavedBufferAttribute ) {
|
|
|
|
count = position.data.count;
|
|
|
|
extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );
|
|
|
|
} else {
|
|
|
|
extension.drawArraysInstancedANGLE( mode, start, count, geometry.maxInstancedCount );
|
|
|
|
}
|
|
|
|
infoRender.calls ++;
|
|
infoRender.vertices += count * geometry.maxInstancedCount;
|
|
|
|
if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
this.setMode = setMode;
|
|
this.render = render;
|
|
this.renderInstances = renderInstances;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLGeometries( gl, attributes, infoMemory ) {
|
|
|
|
var geometries = {};
|
|
var wireframeAttributes = {};
|
|
|
|
function onGeometryDispose( event ) {
|
|
|
|
var geometry = event.target;
|
|
var buffergeometry = geometries[ geometry.id ];
|
|
|
|
if ( buffergeometry.index !== null ) {
|
|
|
|
attributes.remove( buffergeometry.index );
|
|
|
|
}
|
|
|
|
for ( var name in buffergeometry.attributes ) {
|
|
|
|
attributes.remove( buffergeometry.attributes[ name ] );
|
|
|
|
}
|
|
|
|
geometry.removeEventListener( 'dispose', onGeometryDispose );
|
|
|
|
delete geometries[ geometry.id ];
|
|
|
|
// TODO Remove duplicate code
|
|
|
|
var attribute = wireframeAttributes[ geometry.id ];
|
|
|
|
if ( attribute ) {
|
|
|
|
attributes.remove( attribute );
|
|
delete wireframeAttributes[ geometry.id ];
|
|
|
|
}
|
|
|
|
attribute = wireframeAttributes[ buffergeometry.id ];
|
|
|
|
if ( attribute ) {
|
|
|
|
attributes.remove( attribute );
|
|
delete wireframeAttributes[ buffergeometry.id ];
|
|
|
|
}
|
|
|
|
//
|
|
|
|
infoMemory.geometries --;
|
|
|
|
}
|
|
|
|
function get( object, geometry ) {
|
|
|
|
var buffergeometry = geometries[ geometry.id ];
|
|
|
|
if ( buffergeometry ) return buffergeometry;
|
|
|
|
geometry.addEventListener( 'dispose', onGeometryDispose );
|
|
|
|
if ( geometry.isBufferGeometry ) {
|
|
|
|
buffergeometry = geometry;
|
|
|
|
} else if ( geometry.isGeometry ) {
|
|
|
|
if ( geometry._bufferGeometry === undefined ) {
|
|
|
|
geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
|
|
|
|
}
|
|
|
|
buffergeometry = geometry._bufferGeometry;
|
|
|
|
}
|
|
|
|
geometries[ geometry.id ] = buffergeometry;
|
|
|
|
infoMemory.geometries ++;
|
|
|
|
return buffergeometry;
|
|
|
|
}
|
|
|
|
function update( geometry ) {
|
|
|
|
var index = geometry.index;
|
|
var geometryAttributes = geometry.attributes;
|
|
|
|
if ( index !== null ) {
|
|
|
|
attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );
|
|
|
|
}
|
|
|
|
for ( var name in geometryAttributes ) {
|
|
|
|
attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );
|
|
|
|
}
|
|
|
|
// morph targets
|
|
|
|
var morphAttributes = geometry.morphAttributes;
|
|
|
|
for ( var name in morphAttributes ) {
|
|
|
|
var array = morphAttributes[ name ];
|
|
|
|
for ( var i = 0, l = array.length; i < l; i ++ ) {
|
|
|
|
attributes.update( array[ i ], gl.ARRAY_BUFFER );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getWireframeAttribute( geometry ) {
|
|
|
|
var attribute = wireframeAttributes[ geometry.id ];
|
|
|
|
if ( attribute ) return attribute;
|
|
|
|
var indices = [];
|
|
|
|
var geometryIndex = geometry.index;
|
|
var geometryAttributes = geometry.attributes;
|
|
|
|
// console.time( 'wireframe' );
|
|
|
|
if ( geometryIndex !== null ) {
|
|
|
|
var array = geometryIndex.array;
|
|
|
|
for ( var i = 0, l = array.length; i < l; i += 3 ) {
|
|
|
|
var a = array[ i + 0 ];
|
|
var b = array[ i + 1 ];
|
|
var c = array[ i + 2 ];
|
|
|
|
indices.push( a, b, b, c, c, a );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var array = geometryAttributes.position.array;
|
|
|
|
for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
|
|
|
|
var a = i + 0;
|
|
var b = i + 1;
|
|
var c = i + 2;
|
|
|
|
indices.push( a, b, b, c, c, a );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// console.timeEnd( 'wireframe' );
|
|
|
|
attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
|
|
|
attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );
|
|
|
|
wireframeAttributes[ geometry.id ] = attribute;
|
|
|
|
return attribute;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
get: get,
|
|
update: update,
|
|
|
|
getWireframeAttribute: getWireframeAttribute
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLLights() {
|
|
|
|
var lights = {};
|
|
|
|
return {
|
|
|
|
get: function ( light ) {
|
|
|
|
if ( lights[ light.id ] !== undefined ) {
|
|
|
|
return lights[ light.id ];
|
|
|
|
}
|
|
|
|
var uniforms;
|
|
|
|
switch ( light.type ) {
|
|
|
|
case 'DirectionalLight':
|
|
uniforms = {
|
|
direction: new Vector3(),
|
|
color: new Color(),
|
|
|
|
shadow: false,
|
|
shadowBias: 0,
|
|
shadowRadius: 1,
|
|
shadowMapSize: new Vector2()
|
|
};
|
|
break;
|
|
|
|
case 'SpotLight':
|
|
uniforms = {
|
|
position: new Vector3(),
|
|
direction: new Vector3(),
|
|
color: new Color(),
|
|
distance: 0,
|
|
coneCos: 0,
|
|
penumbraCos: 0,
|
|
decay: 0,
|
|
|
|
shadow: false,
|
|
shadowBias: 0,
|
|
shadowRadius: 1,
|
|
shadowMapSize: new Vector2()
|
|
};
|
|
break;
|
|
|
|
case 'PointLight':
|
|
uniforms = {
|
|
position: new Vector3(),
|
|
color: new Color(),
|
|
distance: 0,
|
|
decay: 0,
|
|
|
|
shadow: false,
|
|
shadowBias: 0,
|
|
shadowRadius: 1,
|
|
shadowMapSize: new Vector2()
|
|
};
|
|
break;
|
|
|
|
case 'HemisphereLight':
|
|
uniforms = {
|
|
direction: new Vector3(),
|
|
skyColor: new Color(),
|
|
groundColor: new Color()
|
|
};
|
|
break;
|
|
|
|
case 'RectAreaLight':
|
|
uniforms = {
|
|
color: new Color(),
|
|
position: new Vector3(),
|
|
halfWidth: new Vector3(),
|
|
halfHeight: new Vector3()
|
|
// TODO (abelnation): set RectAreaLight shadow uniforms
|
|
};
|
|
break;
|
|
|
|
}
|
|
|
|
lights[ light.id ] = uniforms;
|
|
|
|
return uniforms;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLObjects( gl, geometries, infoRender ) {
|
|
|
|
var updateList = {};
|
|
|
|
function update( object ) {
|
|
|
|
var frame = infoRender.frame;
|
|
|
|
var geometry = object.geometry;
|
|
var buffergeometry = geometries.get( object, geometry );
|
|
|
|
// Update once per frame
|
|
|
|
if ( updateList[ buffergeometry.id ] !== frame ) {
|
|
|
|
if ( geometry.isGeometry ) {
|
|
|
|
buffergeometry.updateFromObject( object );
|
|
|
|
}
|
|
|
|
geometries.update( buffergeometry );
|
|
|
|
updateList[ buffergeometry.id ] = frame;
|
|
|
|
}
|
|
|
|
return buffergeometry;
|
|
|
|
}
|
|
|
|
function clear() {
|
|
|
|
updateList = {};
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
update: update,
|
|
clear: clear
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function addLineNumbers( string ) {
|
|
|
|
var lines = string.split( '\n' );
|
|
|
|
for ( var i = 0; i < lines.length; i ++ ) {
|
|
|
|
lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
|
|
|
|
}
|
|
|
|
return lines.join( '\n' );
|
|
|
|
}
|
|
|
|
function WebGLShader( gl, type, string ) {
|
|
|
|
var shader = gl.createShader( type );
|
|
|
|
gl.shaderSource( shader, string );
|
|
gl.compileShader( shader );
|
|
|
|
if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
|
|
|
|
console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
|
|
|
|
}
|
|
|
|
if ( gl.getShaderInfoLog( shader ) !== '' ) {
|
|
|
|
console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
|
|
|
|
}
|
|
|
|
// --enable-privileged-webgl-extension
|
|
// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
|
|
|
|
return shader;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
var programIdCount = 0;
|
|
|
|
function getEncodingComponents( encoding ) {
|
|
|
|
switch ( encoding ) {
|
|
|
|
case LinearEncoding:
|
|
return [ 'Linear','( value )' ];
|
|
case sRGBEncoding:
|
|
return [ 'sRGB','( value )' ];
|
|
case RGBEEncoding:
|
|
return [ 'RGBE','( value )' ];
|
|
case RGBM7Encoding:
|
|
return [ 'RGBM','( value, 7.0 )' ];
|
|
case RGBM16Encoding:
|
|
return [ 'RGBM','( value, 16.0 )' ];
|
|
case RGBDEncoding:
|
|
return [ 'RGBD','( value, 256.0 )' ];
|
|
case GammaEncoding:
|
|
return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];
|
|
default:
|
|
throw new Error( 'unsupported encoding: ' + encoding );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getTexelDecodingFunction( functionName, encoding ) {
|
|
|
|
var components = getEncodingComponents( encoding );
|
|
return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }";
|
|
|
|
}
|
|
|
|
function getTexelEncodingFunction( functionName, encoding ) {
|
|
|
|
var components = getEncodingComponents( encoding );
|
|
return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }";
|
|
|
|
}
|
|
|
|
function getToneMappingFunction( functionName, toneMapping ) {
|
|
|
|
var toneMappingName;
|
|
|
|
switch ( toneMapping ) {
|
|
|
|
case LinearToneMapping:
|
|
toneMappingName = "Linear";
|
|
break;
|
|
|
|
case ReinhardToneMapping:
|
|
toneMappingName = "Reinhard";
|
|
break;
|
|
|
|
case Uncharted2ToneMapping:
|
|
toneMappingName = "Uncharted2";
|
|
break;
|
|
|
|
case CineonToneMapping:
|
|
toneMappingName = "OptimizedCineon";
|
|
break;
|
|
|
|
default:
|
|
throw new Error( 'unsupported toneMapping: ' + toneMapping );
|
|
|
|
}
|
|
|
|
return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }";
|
|
|
|
}
|
|
|
|
function generateExtensions( extensions, parameters, rendererExtensions ) {
|
|
|
|
extensions = extensions || {};
|
|
|
|
var chunks = [
|
|
( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
|
|
( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
|
|
( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
|
|
( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''
|
|
];
|
|
|
|
return chunks.filter( filterEmptyLine ).join( '\n' );
|
|
|
|
}
|
|
|
|
function generateDefines( defines ) {
|
|
|
|
var chunks = [];
|
|
|
|
for ( var name in defines ) {
|
|
|
|
var value = defines[ name ];
|
|
|
|
if ( value === false ) continue;
|
|
|
|
chunks.push( '#define ' + name + ' ' + value );
|
|
|
|
}
|
|
|
|
return chunks.join( '\n' );
|
|
|
|
}
|
|
|
|
function fetchAttributeLocations( gl, program, identifiers ) {
|
|
|
|
var attributes = {};
|
|
|
|
var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
|
|
|
|
for ( var i = 0; i < n; i ++ ) {
|
|
|
|
var info = gl.getActiveAttrib( program, i );
|
|
var name = info.name;
|
|
|
|
// console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name, i );
|
|
|
|
attributes[ name ] = gl.getAttribLocation( program, name );
|
|
|
|
}
|
|
|
|
return attributes;
|
|
|
|
}
|
|
|
|
function filterEmptyLine( string ) {
|
|
|
|
return string !== '';
|
|
|
|
}
|
|
|
|
function replaceLightNums( string, parameters ) {
|
|
|
|
return string
|
|
.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
|
|
.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
|
|
.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
|
|
.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
|
|
.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
|
|
|
|
}
|
|
|
|
function parseIncludes( string ) {
|
|
|
|
var pattern = /^[ \t]*#include +<([\w\d.]+)>/gm;
|
|
|
|
function replace( match, include ) {
|
|
|
|
var replace = ShaderChunk[ include ];
|
|
|
|
if ( replace === undefined ) {
|
|
|
|
throw new Error( 'Can not resolve #include <' + include + '>' );
|
|
|
|
}
|
|
|
|
return parseIncludes( replace );
|
|
|
|
}
|
|
|
|
return string.replace( pattern, replace );
|
|
|
|
}
|
|
|
|
function unrollLoops( string ) {
|
|
|
|
var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
|
|
|
|
function replace( match, start, end, snippet ) {
|
|
|
|
var unroll = '';
|
|
|
|
for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
|
|
|
|
unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
|
|
|
|
}
|
|
|
|
return unroll;
|
|
|
|
}
|
|
|
|
return string.replace( pattern, replace );
|
|
|
|
}
|
|
|
|
function WebGLProgram( renderer, code, material, parameters ) {
|
|
|
|
var gl = renderer.context;
|
|
|
|
var extensions = material.extensions;
|
|
var defines = material.defines;
|
|
|
|
var vertexShader = material.__webglShader.vertexShader;
|
|
var fragmentShader = material.__webglShader.fragmentShader;
|
|
|
|
var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
|
|
|
|
if ( parameters.shadowMapType === PCFShadowMap ) {
|
|
|
|
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
|
|
|
|
} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
|
|
|
|
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
|
|
|
|
}
|
|
|
|
var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
|
|
var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
|
|
var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
|
|
|
|
if ( parameters.envMap ) {
|
|
|
|
switch ( material.envMap.mapping ) {
|
|
|
|
case CubeReflectionMapping:
|
|
case CubeRefractionMapping:
|
|
envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
|
|
break;
|
|
|
|
case CubeUVReflectionMapping:
|
|
case CubeUVRefractionMapping:
|
|
envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
|
|
break;
|
|
|
|
case EquirectangularReflectionMapping:
|
|
case EquirectangularRefractionMapping:
|
|
envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
|
|
break;
|
|
|
|
case SphericalReflectionMapping:
|
|
envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
|
|
break;
|
|
|
|
}
|
|
|
|
switch ( material.envMap.mapping ) {
|
|
|
|
case CubeRefractionMapping:
|
|
case EquirectangularRefractionMapping:
|
|
envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
|
|
break;
|
|
|
|
}
|
|
|
|
switch ( material.combine ) {
|
|
|
|
case MultiplyOperation:
|
|
envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
|
|
break;
|
|
|
|
case MixOperation:
|
|
envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
|
|
break;
|
|
|
|
case AddOperation:
|
|
envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
|
|
|
|
// console.log( 'building new program ' );
|
|
|
|
//
|
|
|
|
var customExtensions = generateExtensions( extensions, parameters, renderer.extensions );
|
|
|
|
var customDefines = generateDefines( defines );
|
|
|
|
//
|
|
|
|
var program = gl.createProgram();
|
|
|
|
var prefixVertex, prefixFragment;
|
|
|
|
if ( material.isRawShaderMaterial ) {
|
|
|
|
prefixVertex = [
|
|
|
|
customDefines,
|
|
|
|
'\n'
|
|
|
|
].filter( filterEmptyLine ).join( '\n' );
|
|
|
|
prefixFragment = [
|
|
|
|
customExtensions,
|
|
customDefines,
|
|
|
|
'\n'
|
|
|
|
].filter( filterEmptyLine ).join( '\n' );
|
|
|
|
} else {
|
|
|
|
prefixVertex = [
|
|
|
|
'precision ' + parameters.precision + ' float;',
|
|
'precision ' + parameters.precision + ' int;',
|
|
|
|
'#define SHADER_NAME ' + material.__webglShader.name,
|
|
|
|
customDefines,
|
|
|
|
parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
|
|
|
|
'#define GAMMA_FACTOR ' + gammaFactorDefine,
|
|
|
|
'#define MAX_BONES ' + parameters.maxBones,
|
|
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
|
|
( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
|
|
|
|
parameters.map ? '#define USE_MAP' : '',
|
|
parameters.envMap ? '#define USE_ENVMAP' : '',
|
|
parameters.envMap ? '#define ' + envMapModeDefine : '',
|
|
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
|
|
parameters.aoMap ? '#define USE_AOMAP' : '',
|
|
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
|
|
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
|
|
parameters.normalMap ? '#define USE_NORMALMAP' : '',
|
|
parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
|
|
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
|
|
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
|
|
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
|
|
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
|
|
parameters.vertexColors ? '#define USE_COLOR' : '',
|
|
|
|
parameters.flatShading ? '#define FLAT_SHADED' : '',
|
|
|
|
parameters.skinning ? '#define USE_SKINNING' : '',
|
|
parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
|
|
|
|
parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
|
|
parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
|
|
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
|
|
parameters.flipSided ? '#define FLIP_SIDED' : '',
|
|
|
|
'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
|
|
|
|
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
|
|
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
|
|
|
|
parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
|
|
|
|
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
|
|
parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
|
|
|
|
'uniform mat4 modelMatrix;',
|
|
'uniform mat4 modelViewMatrix;',
|
|
'uniform mat4 projectionMatrix;',
|
|
'uniform mat4 viewMatrix;',
|
|
'uniform mat3 normalMatrix;',
|
|
'uniform vec3 cameraPosition;',
|
|
|
|
'attribute vec3 position;',
|
|
'attribute vec3 normal;',
|
|
'attribute vec2 uv;',
|
|
|
|
'#ifdef USE_COLOR',
|
|
|
|
' attribute vec3 color;',
|
|
|
|
'#endif',
|
|
|
|
'#ifdef USE_MORPHTARGETS',
|
|
|
|
' attribute vec3 morphTarget0;',
|
|
' attribute vec3 morphTarget1;',
|
|
' attribute vec3 morphTarget2;',
|
|
' attribute vec3 morphTarget3;',
|
|
|
|
' #ifdef USE_MORPHNORMALS',
|
|
|
|
' attribute vec3 morphNormal0;',
|
|
' attribute vec3 morphNormal1;',
|
|
' attribute vec3 morphNormal2;',
|
|
' attribute vec3 morphNormal3;',
|
|
|
|
' #else',
|
|
|
|
' attribute vec3 morphTarget4;',
|
|
' attribute vec3 morphTarget5;',
|
|
' attribute vec3 morphTarget6;',
|
|
' attribute vec3 morphTarget7;',
|
|
|
|
' #endif',
|
|
|
|
'#endif',
|
|
|
|
'#ifdef USE_SKINNING',
|
|
|
|
' attribute vec4 skinIndex;',
|
|
' attribute vec4 skinWeight;',
|
|
|
|
'#endif',
|
|
|
|
'\n'
|
|
|
|
].filter( filterEmptyLine ).join( '\n' );
|
|
|
|
prefixFragment = [
|
|
|
|
customExtensions,
|
|
|
|
'precision ' + parameters.precision + ' float;',
|
|
'precision ' + parameters.precision + ' int;',
|
|
|
|
'#define SHADER_NAME ' + material.__webglShader.name,
|
|
|
|
customDefines,
|
|
|
|
parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
|
|
|
|
'#define GAMMA_FACTOR ' + gammaFactorDefine,
|
|
|
|
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
|
|
( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
|
|
|
|
parameters.map ? '#define USE_MAP' : '',
|
|
parameters.envMap ? '#define USE_ENVMAP' : '',
|
|
parameters.envMap ? '#define ' + envMapTypeDefine : '',
|
|
parameters.envMap ? '#define ' + envMapModeDefine : '',
|
|
parameters.envMap ? '#define ' + envMapBlendingDefine : '',
|
|
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
|
|
parameters.aoMap ? '#define USE_AOMAP' : '',
|
|
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
|
|
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
|
|
parameters.normalMap ? '#define USE_NORMALMAP' : '',
|
|
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
|
|
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
|
|
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
|
|
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
|
|
parameters.vertexColors ? '#define USE_COLOR' : '',
|
|
|
|
parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
|
|
|
|
parameters.flatShading ? '#define FLAT_SHADED' : '',
|
|
|
|
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
|
|
parameters.flipSided ? '#define FLIP_SIDED' : '',
|
|
|
|
'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
|
|
'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),
|
|
|
|
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
|
|
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
|
|
|
|
parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
|
|
|
|
parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '',
|
|
|
|
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
|
|
parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
|
|
|
|
parameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
|
|
|
|
'uniform mat4 viewMatrix;',
|
|
'uniform vec3 cameraPosition;',
|
|
|
|
( parameters.toneMapping !== NoToneMapping ) ? "#define TONE_MAPPING" : '',
|
|
( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
|
|
( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '',
|
|
|
|
parameters.dithering ? '#define DITHERING' : '',
|
|
|
|
( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
|
|
parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
|
|
parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
|
|
parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
|
|
parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
|
|
|
|
parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
|
|
|
|
'\n'
|
|
|
|
].filter( filterEmptyLine ).join( '\n' );
|
|
|
|
}
|
|
|
|
vertexShader = parseIncludes( vertexShader, parameters );
|
|
vertexShader = replaceLightNums( vertexShader, parameters );
|
|
|
|
fragmentShader = parseIncludes( fragmentShader, parameters );
|
|
fragmentShader = replaceLightNums( fragmentShader, parameters );
|
|
|
|
if ( ! material.isShaderMaterial ) {
|
|
|
|
vertexShader = unrollLoops( vertexShader );
|
|
fragmentShader = unrollLoops( fragmentShader );
|
|
|
|
}
|
|
|
|
var vertexGlsl = prefixVertex + vertexShader;
|
|
var fragmentGlsl = prefixFragment + fragmentShader;
|
|
|
|
// console.log( '*VERTEX*', vertexGlsl );
|
|
// console.log( '*FRAGMENT*', fragmentGlsl );
|
|
|
|
var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
|
|
var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
|
|
|
|
gl.attachShader( program, glVertexShader );
|
|
gl.attachShader( program, glFragmentShader );
|
|
|
|
// Force a particular attribute to index 0.
|
|
|
|
if ( material.index0AttributeName !== undefined ) {
|
|
|
|
gl.bindAttribLocation( program, 0, material.index0AttributeName );
|
|
|
|
} else if ( parameters.morphTargets === true ) {
|
|
|
|
// programs with morphTargets displace position out of attribute 0
|
|
gl.bindAttribLocation( program, 0, 'position' );
|
|
|
|
}
|
|
|
|
gl.linkProgram( program );
|
|
|
|
var programLog = gl.getProgramInfoLog( program );
|
|
var vertexLog = gl.getShaderInfoLog( glVertexShader );
|
|
var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
|
|
|
|
var runnable = true;
|
|
var haveDiagnostics = true;
|
|
|
|
// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
|
|
// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
|
|
|
|
if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
|
|
|
|
runnable = false;
|
|
|
|
console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
|
|
|
|
} else if ( programLog !== '' ) {
|
|
|
|
console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
|
|
|
|
} else if ( vertexLog === '' || fragmentLog === '' ) {
|
|
|
|
haveDiagnostics = false;
|
|
|
|
}
|
|
|
|
if ( haveDiagnostics ) {
|
|
|
|
this.diagnostics = {
|
|
|
|
runnable: runnable,
|
|
material: material,
|
|
|
|
programLog: programLog,
|
|
|
|
vertexShader: {
|
|
|
|
log: vertexLog,
|
|
prefix: prefixVertex
|
|
|
|
},
|
|
|
|
fragmentShader: {
|
|
|
|
log: fragmentLog,
|
|
prefix: prefixFragment
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// clean up
|
|
|
|
gl.deleteShader( glVertexShader );
|
|
gl.deleteShader( glFragmentShader );
|
|
|
|
// set up caching for uniform locations
|
|
|
|
var cachedUniforms;
|
|
|
|
this.getUniforms = function() {
|
|
|
|
if ( cachedUniforms === undefined ) {
|
|
|
|
cachedUniforms =
|
|
new WebGLUniforms( gl, program, renderer );
|
|
|
|
}
|
|
|
|
return cachedUniforms;
|
|
|
|
};
|
|
|
|
// set up caching for attribute locations
|
|
|
|
var cachedAttributes;
|
|
|
|
this.getAttributes = function() {
|
|
|
|
if ( cachedAttributes === undefined ) {
|
|
|
|
cachedAttributes = fetchAttributeLocations( gl, program );
|
|
|
|
}
|
|
|
|
return cachedAttributes;
|
|
|
|
};
|
|
|
|
// free resource
|
|
|
|
this.destroy = function() {
|
|
|
|
gl.deleteProgram( program );
|
|
this.program = undefined;
|
|
|
|
};
|
|
|
|
// DEPRECATED
|
|
|
|
Object.defineProperties( this, {
|
|
|
|
uniforms: {
|
|
get: function() {
|
|
|
|
console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
|
|
return this.getUniforms();
|
|
|
|
}
|
|
},
|
|
|
|
attributes: {
|
|
get: function() {
|
|
|
|
console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
|
|
return this.getAttributes();
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
//
|
|
|
|
this.id = programIdCount ++;
|
|
this.code = code;
|
|
this.usedTimes = 1;
|
|
this.program = program;
|
|
this.vertexShader = glVertexShader;
|
|
this.fragmentShader = glFragmentShader;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLPrograms( renderer, capabilities ) {
|
|
|
|
var programs = [];
|
|
|
|
var shaderIDs = {
|
|
MeshDepthMaterial: 'depth',
|
|
MeshNormalMaterial: 'normal',
|
|
MeshBasicMaterial: 'basic',
|
|
MeshLambertMaterial: 'lambert',
|
|
MeshPhongMaterial: 'phong',
|
|
MeshToonMaterial: 'phong',
|
|
MeshStandardMaterial: 'physical',
|
|
MeshPhysicalMaterial: 'physical',
|
|
LineBasicMaterial: 'basic',
|
|
LineDashedMaterial: 'dashed',
|
|
PointsMaterial: 'points'
|
|
};
|
|
|
|
var parameterNames = [
|
|
"precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding",
|
|
"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap",
|
|
"roughnessMap", "metalnessMap", "gradientMap",
|
|
"alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
|
|
"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
|
|
"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
|
|
"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
|
|
"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
|
|
"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
|
|
"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering"
|
|
];
|
|
|
|
|
|
function allocateBones( object ) {
|
|
|
|
var skeleton = object.skeleton;
|
|
var bones = skeleton.bones;
|
|
|
|
if ( capabilities.floatVertexTextures ) {
|
|
|
|
return 1024;
|
|
|
|
} else {
|
|
|
|
// default for when object is not specified
|
|
// ( for example when prebuilding shader to be used with multiple objects )
|
|
//
|
|
// - leave some extra space for other uniforms
|
|
// - limit here is ANGLE's 254 max uniform vectors
|
|
// (up to 54 should be safe)
|
|
|
|
var nVertexUniforms = capabilities.maxVertexUniforms;
|
|
var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
|
|
|
|
var maxBones = Math.min( nVertexMatrices, bones.length );
|
|
|
|
if ( maxBones < bones.length ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
|
|
return 0;
|
|
|
|
}
|
|
|
|
return maxBones;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
|
|
|
|
var encoding;
|
|
|
|
if ( ! map ) {
|
|
|
|
encoding = LinearEncoding;
|
|
|
|
} else if ( map.isTexture ) {
|
|
|
|
encoding = map.encoding;
|
|
|
|
} else if ( map.isWebGLRenderTarget ) {
|
|
|
|
console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
|
|
encoding = map.texture.encoding;
|
|
|
|
}
|
|
|
|
// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.
|
|
if ( encoding === LinearEncoding && gammaOverrideLinear ) {
|
|
|
|
encoding = GammaEncoding;
|
|
|
|
}
|
|
|
|
return encoding;
|
|
|
|
}
|
|
|
|
this.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {
|
|
|
|
var shaderID = shaderIDs[ material.type ];
|
|
|
|
// heuristics to create shader parameters according to lights in the scene
|
|
// (not to blow over maxLights budget)
|
|
|
|
var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
|
|
var precision = renderer.getPrecision();
|
|
|
|
if ( material.precision !== null ) {
|
|
|
|
precision = capabilities.getMaxPrecision( material.precision );
|
|
|
|
if ( precision !== material.precision ) {
|
|
|
|
console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var currentRenderTarget = renderer.getRenderTarget();
|
|
|
|
var parameters = {
|
|
|
|
shaderID: shaderID,
|
|
|
|
precision: precision,
|
|
supportsVertexTextures: capabilities.vertexTextures,
|
|
outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
|
|
map: !! material.map,
|
|
mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
|
|
envMap: !! material.envMap,
|
|
envMapMode: material.envMap && material.envMap.mapping,
|
|
envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
|
|
envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
|
|
lightMap: !! material.lightMap,
|
|
aoMap: !! material.aoMap,
|
|
emissiveMap: !! material.emissiveMap,
|
|
emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
|
|
bumpMap: !! material.bumpMap,
|
|
normalMap: !! material.normalMap,
|
|
displacementMap: !! material.displacementMap,
|
|
roughnessMap: !! material.roughnessMap,
|
|
metalnessMap: !! material.metalnessMap,
|
|
specularMap: !! material.specularMap,
|
|
alphaMap: !! material.alphaMap,
|
|
|
|
gradientMap: !! material.gradientMap,
|
|
|
|
combine: material.combine,
|
|
|
|
vertexColors: material.vertexColors,
|
|
|
|
fog: !! fog,
|
|
useFog: material.fog,
|
|
fogExp: ( fog && fog.isFogExp2 ),
|
|
|
|
flatShading: material.shading === FlatShading,
|
|
|
|
sizeAttenuation: material.sizeAttenuation,
|
|
logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
|
|
|
|
skinning: material.skinning && maxBones > 0,
|
|
maxBones: maxBones,
|
|
useVertexTexture: capabilities.floatVertexTextures,
|
|
|
|
morphTargets: material.morphTargets,
|
|
morphNormals: material.morphNormals,
|
|
maxMorphTargets: renderer.maxMorphTargets,
|
|
maxMorphNormals: renderer.maxMorphNormals,
|
|
|
|
numDirLights: lights.directional.length,
|
|
numPointLights: lights.point.length,
|
|
numSpotLights: lights.spot.length,
|
|
numRectAreaLights: lights.rectArea.length,
|
|
numHemiLights: lights.hemi.length,
|
|
|
|
numClippingPlanes: nClipPlanes,
|
|
numClipIntersection: nClipIntersection,
|
|
|
|
dithering: material.dithering,
|
|
|
|
shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,
|
|
shadowMapType: renderer.shadowMap.type,
|
|
|
|
toneMapping: renderer.toneMapping,
|
|
physicallyCorrectLights: renderer.physicallyCorrectLights,
|
|
|
|
premultipliedAlpha: material.premultipliedAlpha,
|
|
|
|
alphaTest: material.alphaTest,
|
|
doubleSided: material.side === DoubleSide,
|
|
flipSided: material.side === BackSide,
|
|
|
|
depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
|
|
|
|
};
|
|
|
|
return parameters;
|
|
|
|
};
|
|
|
|
this.getProgramCode = function ( material, parameters ) {
|
|
|
|
var array = [];
|
|
|
|
if ( parameters.shaderID ) {
|
|
|
|
array.push( parameters.shaderID );
|
|
|
|
} else {
|
|
|
|
array.push( material.fragmentShader );
|
|
array.push( material.vertexShader );
|
|
|
|
}
|
|
|
|
if ( material.defines !== undefined ) {
|
|
|
|
for ( var name in material.defines ) {
|
|
|
|
array.push( name );
|
|
array.push( material.defines[ name ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < parameterNames.length; i ++ ) {
|
|
|
|
array.push( parameters[ parameterNames[ i ] ] );
|
|
|
|
}
|
|
|
|
return array.join();
|
|
|
|
};
|
|
|
|
this.acquireProgram = function ( material, parameters, code ) {
|
|
|
|
var program;
|
|
|
|
// Check if code has been already compiled
|
|
for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
|
|
|
|
var programInfo = programs[ p ];
|
|
|
|
if ( programInfo.code === code ) {
|
|
|
|
program = programInfo;
|
|
++ program.usedTimes;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( program === undefined ) {
|
|
|
|
program = new WebGLProgram( renderer, code, material, parameters );
|
|
programs.push( program );
|
|
|
|
}
|
|
|
|
return program;
|
|
|
|
};
|
|
|
|
this.releaseProgram = function ( program ) {
|
|
|
|
if ( -- program.usedTimes === 0 ) {
|
|
|
|
// Remove from unordered set
|
|
var i = programs.indexOf( program );
|
|
programs[ i ] = programs[ programs.length - 1 ];
|
|
programs.pop();
|
|
|
|
// Free WebGL resources
|
|
program.destroy();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Exposed for resource monitoring & error feedback via renderer.info:
|
|
this.programs = programs;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, infoMemory ) {
|
|
|
|
var _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );
|
|
|
|
//
|
|
|
|
function clampToMaxSize( image, maxSize ) {
|
|
|
|
if ( image.width > maxSize || image.height > maxSize ) {
|
|
|
|
// Warning: Scaling through the canvas will only work with images that use
|
|
// premultiplied alpha.
|
|
|
|
var scale = maxSize / Math.max( image.width, image.height );
|
|
|
|
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
|
|
canvas.width = Math.floor( image.width * scale );
|
|
canvas.height = Math.floor( image.height * scale );
|
|
|
|
var context = canvas.getContext( '2d' );
|
|
context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
|
|
|
|
console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
|
|
|
|
return canvas;
|
|
|
|
}
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
function isPowerOfTwo( image ) {
|
|
|
|
return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );
|
|
|
|
}
|
|
|
|
function makePowerOfTwo( image ) {
|
|
|
|
if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
|
|
|
|
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
|
|
canvas.width = _Math.nearestPowerOfTwo( image.width );
|
|
canvas.height = _Math.nearestPowerOfTwo( image.height );
|
|
|
|
var context = canvas.getContext( '2d' );
|
|
context.drawImage( image, 0, 0, canvas.width, canvas.height );
|
|
|
|
console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
|
|
|
|
return canvas;
|
|
|
|
}
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
function textureNeedsPowerOfTwo( texture ) {
|
|
|
|
return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
|
|
( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
|
|
|
|
}
|
|
|
|
// Fallback filters for non-power-of-2 textures
|
|
|
|
function filterFallback( f ) {
|
|
|
|
if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {
|
|
|
|
return _gl.NEAREST;
|
|
|
|
}
|
|
|
|
return _gl.LINEAR;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function onTextureDispose( event ) {
|
|
|
|
var texture = event.target;
|
|
|
|
texture.removeEventListener( 'dispose', onTextureDispose );
|
|
|
|
deallocateTexture( texture );
|
|
|
|
infoMemory.textures --;
|
|
|
|
|
|
}
|
|
|
|
function onRenderTargetDispose( event ) {
|
|
|
|
var renderTarget = event.target;
|
|
|
|
renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
|
|
|
|
deallocateRenderTarget( renderTarget );
|
|
|
|
infoMemory.textures --;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function deallocateTexture( texture ) {
|
|
|
|
var textureProperties = properties.get( texture );
|
|
|
|
if ( texture.image && textureProperties.__image__webglTextureCube ) {
|
|
|
|
// cube texture
|
|
|
|
_gl.deleteTexture( textureProperties.__image__webglTextureCube );
|
|
|
|
} else {
|
|
|
|
// 2D texture
|
|
|
|
if ( textureProperties.__webglInit === undefined ) return;
|
|
|
|
_gl.deleteTexture( textureProperties.__webglTexture );
|
|
|
|
}
|
|
|
|
// remove all webgl properties
|
|
properties.remove( texture );
|
|
|
|
}
|
|
|
|
function deallocateRenderTarget( renderTarget ) {
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
if ( ! renderTarget ) return;
|
|
|
|
if ( textureProperties.__webglTexture !== undefined ) {
|
|
|
|
_gl.deleteTexture( textureProperties.__webglTexture );
|
|
|
|
}
|
|
|
|
if ( renderTarget.depthTexture ) {
|
|
|
|
renderTarget.depthTexture.dispose();
|
|
|
|
}
|
|
|
|
if ( renderTarget.isWebGLRenderTargetCube ) {
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
|
|
if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
|
|
if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
|
|
|
|
}
|
|
|
|
properties.remove( renderTarget.texture );
|
|
properties.remove( renderTarget );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
|
|
|
|
function setTexture2D( texture, slot ) {
|
|
|
|
var textureProperties = properties.get( texture );
|
|
|
|
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
|
|
|
|
var image = texture.image;
|
|
|
|
if ( image === undefined ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
|
|
|
|
} else if ( image.complete === false ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
|
|
|
|
} else {
|
|
|
|
uploadTexture( textureProperties, texture, slot );
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
state.activeTexture( _gl.TEXTURE0 + slot );
|
|
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
}
|
|
|
|
function setTextureCube( texture, slot ) {
|
|
|
|
var textureProperties = properties.get( texture );
|
|
|
|
if ( texture.image.length === 6 ) {
|
|
|
|
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
|
|
|
|
if ( ! textureProperties.__image__webglTextureCube ) {
|
|
|
|
texture.addEventListener( 'dispose', onTextureDispose );
|
|
|
|
textureProperties.__image__webglTextureCube = _gl.createTexture();
|
|
|
|
infoMemory.textures ++;
|
|
|
|
}
|
|
|
|
state.activeTexture( _gl.TEXTURE0 + slot );
|
|
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
|
|
|
|
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
|
|
|
|
var isCompressed = ( texture && texture.isCompressedTexture );
|
|
var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
|
|
|
|
var cubeImage = [];
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
if ( ! isCompressed && ! isDataTexture ) {
|
|
|
|
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
|
|
|
|
} else {
|
|
|
|
cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var image = cubeImage[ 0 ],
|
|
isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
if ( ! isCompressed ) {
|
|
|
|
if ( isDataTexture ) {
|
|
|
|
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
|
|
|
|
} else {
|
|
|
|
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var mipmap, mipmaps = cubeImage[ i ].mipmaps;
|
|
|
|
for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
|
|
|
|
mipmap = mipmaps[ j ];
|
|
|
|
if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
|
|
|
|
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
} else {
|
|
|
|
console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( texture.generateMipmaps && isPowerOfTwoImage ) {
|
|
|
|
_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
}
|
|
|
|
textureProperties.__version = texture.version;
|
|
|
|
if ( texture.onUpdate ) texture.onUpdate( texture );
|
|
|
|
} else {
|
|
|
|
state.activeTexture( _gl.TEXTURE0 + slot );
|
|
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setTextureCubeDynamic( texture, slot ) {
|
|
|
|
state.activeTexture( _gl.TEXTURE0 + slot );
|
|
state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
|
|
|
|
}
|
|
|
|
function setTextureParameters( textureType, texture, isPowerOfTwoImage ) {
|
|
|
|
var extension;
|
|
|
|
if ( isPowerOfTwoImage ) {
|
|
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
|
|
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
|
|
|
|
} else {
|
|
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
|
|
|
|
if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
|
|
|
|
}
|
|
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
|
|
_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
|
|
|
|
if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extension = extensions.get( 'EXT_texture_filter_anisotropic' );
|
|
|
|
if ( extension ) {
|
|
|
|
if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
|
|
if ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
|
|
|
|
if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
|
|
|
|
_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
|
|
properties.get( texture ).__currentAnisotropy = texture.anisotropy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function uploadTexture( textureProperties, texture, slot ) {
|
|
|
|
if ( textureProperties.__webglInit === undefined ) {
|
|
|
|
textureProperties.__webglInit = true;
|
|
|
|
texture.addEventListener( 'dispose', onTextureDispose );
|
|
|
|
textureProperties.__webglTexture = _gl.createTexture();
|
|
|
|
infoMemory.textures ++;
|
|
|
|
}
|
|
|
|
state.activeTexture( _gl.TEXTURE0 + slot );
|
|
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
|
|
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
|
|
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
|
|
|
|
var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
|
|
|
|
if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
|
|
|
|
image = makePowerOfTwo( image );
|
|
|
|
}
|
|
|
|
var isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
|
|
|
|
var mipmap, mipmaps = texture.mipmaps;
|
|
|
|
if ( texture.isDepthTexture ) {
|
|
|
|
// populate depth texture with dummy data
|
|
|
|
var internalFormat = _gl.DEPTH_COMPONENT;
|
|
|
|
if ( texture.type === FloatType ) {
|
|
|
|
if ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');
|
|
internalFormat = _gl.DEPTH_COMPONENT32F;
|
|
|
|
} else if ( _isWebGL2 ) {
|
|
|
|
// WebGL 2.0 requires signed internalformat for glTexImage2D
|
|
internalFormat = _gl.DEPTH_COMPONENT16;
|
|
|
|
}
|
|
|
|
if ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {
|
|
|
|
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
|
|
// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
|
|
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
|
|
if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
|
|
|
|
texture.type = UnsignedShortType;
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Depth stencil textures need the DEPTH_STENCIL internal format
|
|
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
|
|
if ( texture.format === DepthStencilFormat ) {
|
|
|
|
internalFormat = _gl.DEPTH_STENCIL;
|
|
|
|
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
|
|
// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
|
|
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
|
|
if ( texture.type !== UnsignedInt248Type ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
|
|
|
|
texture.type = UnsignedInt248Type;
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );
|
|
|
|
} else if ( texture.isDataTexture ) {
|
|
|
|
// use manually created mipmaps if available
|
|
// if there are no manual mipmaps
|
|
// set 0 level mipmap and then use GL to generate other mipmap levels
|
|
|
|
if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
|
|
|
|
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
mipmap = mipmaps[ i ];
|
|
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
}
|
|
|
|
texture.generateMipmaps = false;
|
|
|
|
} else {
|
|
|
|
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
|
|
|
|
}
|
|
|
|
} else if ( texture.isCompressedTexture ) {
|
|
|
|
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
mipmap = mipmaps[ i ];
|
|
|
|
if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
|
|
|
|
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
} else {
|
|
|
|
console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// regular Texture (image, video, canvas)
|
|
|
|
// use manually created mipmaps if available
|
|
// if there are no manual mipmaps
|
|
// set 0 level mipmap and then use GL to generate other mipmap levels
|
|
|
|
if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
|
|
|
|
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
mipmap = mipmaps[ i ];
|
|
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
|
|
|
|
}
|
|
|
|
texture.generateMipmaps = false;
|
|
|
|
} else {
|
|
|
|
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
textureProperties.__version = texture.version;
|
|
|
|
if ( texture.onUpdate ) texture.onUpdate( texture );
|
|
|
|
}
|
|
|
|
// Render targets
|
|
|
|
// Setup storage for target texture and bind it to correct framebuffer
|
|
function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
|
|
|
|
var glFormat = paramThreeToGL( renderTarget.texture.format );
|
|
var glType = paramThreeToGL( renderTarget.texture.type );
|
|
state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
|
|
|
|
}
|
|
|
|
// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
|
|
function setupRenderBufferStorage( renderbuffer, renderTarget ) {
|
|
|
|
_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
|
|
|
|
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
|
|
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
|
|
|
|
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
|
|
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
} else {
|
|
|
|
// FIXME: We don't support !depth !stencil
|
|
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
|
|
|
|
}
|
|
|
|
_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
|
|
|
|
}
|
|
|
|
// Setup resources for a Depth Texture for a FBO (needs an extension)
|
|
function setupDepthTexture( framebuffer, renderTarget ) {
|
|
|
|
var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
|
|
if ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
|
|
if ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
|
|
|
|
throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
|
|
|
|
}
|
|
|
|
// upload an empty depth texture with framebuffer size
|
|
if ( !properties.get( renderTarget.depthTexture ).__webglTexture ||
|
|
renderTarget.depthTexture.image.width !== renderTarget.width ||
|
|
renderTarget.depthTexture.image.height !== renderTarget.height ) {
|
|
renderTarget.depthTexture.image.width = renderTarget.width;
|
|
renderTarget.depthTexture.image.height = renderTarget.height;
|
|
renderTarget.depthTexture.needsUpdate = true;
|
|
}
|
|
|
|
setTexture2D( renderTarget.depthTexture, 0 );
|
|
|
|
var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
|
|
|
|
if ( renderTarget.depthTexture.format === DepthFormat ) {
|
|
|
|
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
|
|
|
|
} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
|
|
|
|
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
|
|
|
|
} else {
|
|
|
|
throw new Error('Unknown depthTexture format')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Setup GL resources for a non-texture depth buffer
|
|
function setupDepthRenderbuffer( renderTarget ) {
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
|
|
|
|
if ( renderTarget.depthTexture ) {
|
|
|
|
if ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');
|
|
|
|
setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
|
|
|
|
} else {
|
|
|
|
if ( isCube ) {
|
|
|
|
renderTargetProperties.__webglDepthbuffer = [];
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
|
|
renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
|
|
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
|
|
renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
|
|
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
|
|
|
|
}
|
|
|
|
// Set up GL resources for the render target
|
|
function setupRenderTarget( renderTarget ) {
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
|
|
|
|
textureProperties.__webglTexture = _gl.createTexture();
|
|
|
|
infoMemory.textures ++;
|
|
|
|
var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
|
|
var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
|
|
|
|
// Setup framebuffer
|
|
|
|
if ( isCube ) {
|
|
|
|
renderTargetProperties.__webglFramebuffer = [];
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
|
|
|
|
}
|
|
|
|
// Setup color buffer
|
|
|
|
if ( isCube ) {
|
|
|
|
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
|
|
setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
|
|
|
|
}
|
|
|
|
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
|
|
|
|
} else {
|
|
|
|
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
|
|
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
|
|
|
|
if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
state.bindTexture( _gl.TEXTURE_2D, null );
|
|
|
|
}
|
|
|
|
// Setup depth and stencil buffers
|
|
|
|
if ( renderTarget.depthBuffer ) {
|
|
|
|
setupDepthRenderbuffer( renderTarget );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function updateRenderTargetMipmap( renderTarget ) {
|
|
|
|
var texture = renderTarget.texture;
|
|
|
|
if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
|
|
texture.minFilter !== NearestFilter &&
|
|
texture.minFilter !== LinearFilter ) {
|
|
|
|
var target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
|
|
var webglTexture = properties.get( texture ).__webglTexture;
|
|
|
|
state.bindTexture( target, webglTexture );
|
|
_gl.generateMipmap( target );
|
|
state.bindTexture( target, null );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.setTexture2D = setTexture2D;
|
|
this.setTextureCube = setTextureCube;
|
|
this.setTextureCubeDynamic = setTextureCubeDynamic;
|
|
this.setupRenderTarget = setupRenderTarget;
|
|
this.updateRenderTargetMipmap = updateRenderTargetMipmap;
|
|
|
|
}
|
|
|
|
/**
|
|
* @author fordacious / fordacious.github.io
|
|
*/
|
|
|
|
function WebGLProperties() {
|
|
|
|
var properties = {};
|
|
|
|
function get( object ) {
|
|
|
|
var uuid = object.uuid;
|
|
var map = properties[ uuid ];
|
|
|
|
if ( map === undefined ) {
|
|
|
|
map = {};
|
|
properties[ uuid ] = map;
|
|
|
|
}
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
function remove( object ) {
|
|
|
|
delete properties[ object.uuid ];
|
|
|
|
}
|
|
|
|
function clear() {
|
|
|
|
properties = {};
|
|
|
|
}
|
|
|
|
return {
|
|
get: get,
|
|
remove: remove,
|
|
clear: clear
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLState( gl, extensions, paramThreeToGL ) {
|
|
|
|
function ColorBuffer() {
|
|
|
|
var locked = false;
|
|
|
|
var color = new Vector4();
|
|
var currentColorMask = null;
|
|
var currentColorClear = new Vector4();
|
|
|
|
return {
|
|
|
|
setMask: function ( colorMask ) {
|
|
|
|
if ( currentColorMask !== colorMask && ! locked ) {
|
|
|
|
gl.colorMask( colorMask, colorMask, colorMask, colorMask );
|
|
currentColorMask = colorMask;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setLocked: function ( lock ) {
|
|
|
|
locked = lock;
|
|
|
|
},
|
|
|
|
setClear: function ( r, g, b, a, premultipliedAlpha ) {
|
|
|
|
if ( premultipliedAlpha === true ) {
|
|
|
|
r *= a; g *= a; b *= a;
|
|
|
|
}
|
|
|
|
color.set( r, g, b, a );
|
|
|
|
if ( currentColorClear.equals( color ) === false ) {
|
|
|
|
gl.clearColor( r, g, b, a );
|
|
currentColorClear.copy( color );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
reset: function () {
|
|
|
|
locked = false;
|
|
|
|
currentColorMask = null;
|
|
currentColorClear.set( 0, 0, 0, 1 );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function DepthBuffer() {
|
|
|
|
var locked = false;
|
|
|
|
var currentDepthMask = null;
|
|
var currentDepthFunc = null;
|
|
var currentDepthClear = null;
|
|
|
|
return {
|
|
|
|
setTest: function ( depthTest ) {
|
|
|
|
if ( depthTest ) {
|
|
|
|
enable( gl.DEPTH_TEST );
|
|
|
|
} else {
|
|
|
|
disable( gl.DEPTH_TEST );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setMask: function ( depthMask ) {
|
|
|
|
if ( currentDepthMask !== depthMask && ! locked ) {
|
|
|
|
gl.depthMask( depthMask );
|
|
currentDepthMask = depthMask;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setFunc: function ( depthFunc ) {
|
|
|
|
if ( currentDepthFunc !== depthFunc ) {
|
|
|
|
if ( depthFunc ) {
|
|
|
|
switch ( depthFunc ) {
|
|
|
|
case NeverDepth:
|
|
|
|
gl.depthFunc( gl.NEVER );
|
|
break;
|
|
|
|
case AlwaysDepth:
|
|
|
|
gl.depthFunc( gl.ALWAYS );
|
|
break;
|
|
|
|
case LessDepth:
|
|
|
|
gl.depthFunc( gl.LESS );
|
|
break;
|
|
|
|
case LessEqualDepth:
|
|
|
|
gl.depthFunc( gl.LEQUAL );
|
|
break;
|
|
|
|
case EqualDepth:
|
|
|
|
gl.depthFunc( gl.EQUAL );
|
|
break;
|
|
|
|
case GreaterEqualDepth:
|
|
|
|
gl.depthFunc( gl.GEQUAL );
|
|
break;
|
|
|
|
case GreaterDepth:
|
|
|
|
gl.depthFunc( gl.GREATER );
|
|
break;
|
|
|
|
case NotEqualDepth:
|
|
|
|
gl.depthFunc( gl.NOTEQUAL );
|
|
break;
|
|
|
|
default:
|
|
|
|
gl.depthFunc( gl.LEQUAL );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gl.depthFunc( gl.LEQUAL );
|
|
|
|
}
|
|
|
|
currentDepthFunc = depthFunc;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setLocked: function ( lock ) {
|
|
|
|
locked = lock;
|
|
|
|
},
|
|
|
|
setClear: function ( depth ) {
|
|
|
|
if ( currentDepthClear !== depth ) {
|
|
|
|
gl.clearDepth( depth );
|
|
currentDepthClear = depth;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
reset: function () {
|
|
|
|
locked = false;
|
|
|
|
currentDepthMask = null;
|
|
currentDepthFunc = null;
|
|
currentDepthClear = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function StencilBuffer() {
|
|
|
|
var locked = false;
|
|
|
|
var currentStencilMask = null;
|
|
var currentStencilFunc = null;
|
|
var currentStencilRef = null;
|
|
var currentStencilFuncMask = null;
|
|
var currentStencilFail = null;
|
|
var currentStencilZFail = null;
|
|
var currentStencilZPass = null;
|
|
var currentStencilClear = null;
|
|
|
|
return {
|
|
|
|
setTest: function ( stencilTest ) {
|
|
|
|
if ( stencilTest ) {
|
|
|
|
enable( gl.STENCIL_TEST );
|
|
|
|
} else {
|
|
|
|
disable( gl.STENCIL_TEST );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setMask: function ( stencilMask ) {
|
|
|
|
if ( currentStencilMask !== stencilMask && ! locked ) {
|
|
|
|
gl.stencilMask( stencilMask );
|
|
currentStencilMask = stencilMask;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
|
|
|
|
if ( currentStencilFunc !== stencilFunc ||
|
|
currentStencilRef !== stencilRef ||
|
|
currentStencilFuncMask !== stencilMask ) {
|
|
|
|
gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
|
|
|
|
currentStencilFunc = stencilFunc;
|
|
currentStencilRef = stencilRef;
|
|
currentStencilFuncMask = stencilMask;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
|
|
|
|
if ( currentStencilFail !== stencilFail ||
|
|
currentStencilZFail !== stencilZFail ||
|
|
currentStencilZPass !== stencilZPass ) {
|
|
|
|
gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
|
|
|
|
currentStencilFail = stencilFail;
|
|
currentStencilZFail = stencilZFail;
|
|
currentStencilZPass = stencilZPass;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setLocked: function ( lock ) {
|
|
|
|
locked = lock;
|
|
|
|
},
|
|
|
|
setClear: function ( stencil ) {
|
|
|
|
if ( currentStencilClear !== stencil ) {
|
|
|
|
gl.clearStencil( stencil );
|
|
currentStencilClear = stencil;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
reset: function () {
|
|
|
|
locked = false;
|
|
|
|
currentStencilMask = null;
|
|
currentStencilFunc = null;
|
|
currentStencilRef = null;
|
|
currentStencilFuncMask = null;
|
|
currentStencilFail = null;
|
|
currentStencilZFail = null;
|
|
currentStencilZPass = null;
|
|
currentStencilClear = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var colorBuffer = new ColorBuffer();
|
|
var depthBuffer = new DepthBuffer();
|
|
var stencilBuffer = new StencilBuffer();
|
|
|
|
var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
|
|
var newAttributes = new Uint8Array( maxVertexAttributes );
|
|
var enabledAttributes = new Uint8Array( maxVertexAttributes );
|
|
var attributeDivisors = new Uint8Array( maxVertexAttributes );
|
|
|
|
var capabilities = {};
|
|
|
|
var compressedTextureFormats = null;
|
|
|
|
var currentBlending = null;
|
|
var currentBlendEquation = null;
|
|
var currentBlendSrc = null;
|
|
var currentBlendDst = null;
|
|
var currentBlendEquationAlpha = null;
|
|
var currentBlendSrcAlpha = null;
|
|
var currentBlendDstAlpha = null;
|
|
var currentPremultipledAlpha = false;
|
|
|
|
var currentFlipSided = null;
|
|
var currentCullFace = null;
|
|
|
|
var currentLineWidth = null;
|
|
|
|
var currentPolygonOffsetFactor = null;
|
|
var currentPolygonOffsetUnits = null;
|
|
|
|
var currentScissorTest = null;
|
|
|
|
var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
|
|
|
|
var version = parseFloat( /^WebGL\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );
|
|
var lineWidthAvailable = parseFloat( version ) >= 1.0;
|
|
|
|
var currentTextureSlot = null;
|
|
var currentBoundTextures = {};
|
|
|
|
var currentScissor = new Vector4();
|
|
var currentViewport = new Vector4();
|
|
|
|
function createTexture( type, target, count ) {
|
|
|
|
var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.
|
|
var texture = gl.createTexture();
|
|
|
|
gl.bindTexture( type, texture );
|
|
gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
|
|
gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
|
|
|
|
for ( var i = 0; i < count; i ++ ) {
|
|
|
|
gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );
|
|
|
|
}
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
var emptyTextures = {};
|
|
emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );
|
|
emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );
|
|
|
|
//
|
|
|
|
function init() {
|
|
|
|
colorBuffer.setClear( 0, 0, 0, 1 );
|
|
depthBuffer.setClear( 1 );
|
|
stencilBuffer.setClear( 0 );
|
|
|
|
enable( gl.DEPTH_TEST );
|
|
depthBuffer.setFunc( LessEqualDepth );
|
|
|
|
setFlipSided( false );
|
|
setCullFace( CullFaceBack );
|
|
enable( gl.CULL_FACE );
|
|
|
|
enable( gl.BLEND );
|
|
setBlending( NormalBlending );
|
|
|
|
}
|
|
|
|
function initAttributes() {
|
|
|
|
for ( var i = 0, l = newAttributes.length; i < l; i ++ ) {
|
|
|
|
newAttributes[ i ] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function enableAttribute( attribute ) {
|
|
|
|
newAttributes[ attribute ] = 1;
|
|
|
|
if ( enabledAttributes[ attribute ] === 0 ) {
|
|
|
|
gl.enableVertexAttribArray( attribute );
|
|
enabledAttributes[ attribute ] = 1;
|
|
|
|
}
|
|
|
|
if ( attributeDivisors[ attribute ] !== 0 ) {
|
|
|
|
var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
extension.vertexAttribDivisorANGLE( attribute, 0 );
|
|
attributeDivisors[ attribute ] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
|
|
|
|
newAttributes[ attribute ] = 1;
|
|
|
|
if ( enabledAttributes[ attribute ] === 0 ) {
|
|
|
|
gl.enableVertexAttribArray( attribute );
|
|
enabledAttributes[ attribute ] = 1;
|
|
|
|
}
|
|
|
|
if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
|
|
|
|
var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );
|
|
attributeDivisors[ attribute ] = meshPerAttribute;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function disableUnusedAttributes() {
|
|
|
|
for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {
|
|
|
|
if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
|
|
|
|
gl.disableVertexAttribArray( i );
|
|
enabledAttributes[ i ] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function enable( id ) {
|
|
|
|
if ( capabilities[ id ] !== true ) {
|
|
|
|
gl.enable( id );
|
|
capabilities[ id ] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function disable( id ) {
|
|
|
|
if ( capabilities[ id ] !== false ) {
|
|
|
|
gl.disable( id );
|
|
capabilities[ id ] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getCompressedTextureFormats() {
|
|
|
|
if ( compressedTextureFormats === null ) {
|
|
|
|
compressedTextureFormats = [];
|
|
|
|
if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||
|
|
extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||
|
|
extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {
|
|
|
|
var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );
|
|
|
|
for ( var i = 0; i < formats.length; i ++ ) {
|
|
|
|
compressedTextureFormats.push( formats[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return compressedTextureFormats;
|
|
|
|
}
|
|
|
|
function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
|
|
|
|
if ( blending !== NoBlending ) {
|
|
|
|
enable( gl.BLEND );
|
|
|
|
} else {
|
|
|
|
disable( gl.BLEND );
|
|
|
|
}
|
|
|
|
if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {
|
|
|
|
if ( blending === AdditiveBlending ) {
|
|
|
|
if ( premultipliedAlpha ) {
|
|
|
|
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
|
|
gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );
|
|
|
|
} else {
|
|
|
|
gl.blendEquation( gl.FUNC_ADD );
|
|
gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
|
|
|
|
}
|
|
|
|
} else if ( blending === SubtractiveBlending ) {
|
|
|
|
if ( premultipliedAlpha ) {
|
|
|
|
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
|
|
gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );
|
|
|
|
} else {
|
|
|
|
gl.blendEquation( gl.FUNC_ADD );
|
|
gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );
|
|
|
|
}
|
|
|
|
} else if ( blending === MultiplyBlending ) {
|
|
|
|
if ( premultipliedAlpha ) {
|
|
|
|
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
|
|
gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );
|
|
|
|
} else {
|
|
|
|
gl.blendEquation( gl.FUNC_ADD );
|
|
gl.blendFunc( gl.ZERO, gl.SRC_COLOR );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( premultipliedAlpha ) {
|
|
|
|
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
|
|
gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
|
|
|
|
} else {
|
|
|
|
gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
|
|
gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
currentBlending = blending;
|
|
currentPremultipledAlpha = premultipliedAlpha;
|
|
|
|
}
|
|
|
|
if ( blending === CustomBlending ) {
|
|
|
|
blendEquationAlpha = blendEquationAlpha || blendEquation;
|
|
blendSrcAlpha = blendSrcAlpha || blendSrc;
|
|
blendDstAlpha = blendDstAlpha || blendDst;
|
|
|
|
if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
|
|
|
|
gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );
|
|
|
|
currentBlendEquation = blendEquation;
|
|
currentBlendEquationAlpha = blendEquationAlpha;
|
|
|
|
}
|
|
|
|
if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
|
|
|
|
gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );
|
|
|
|
currentBlendSrc = blendSrc;
|
|
currentBlendDst = blendDst;
|
|
currentBlendSrcAlpha = blendSrcAlpha;
|
|
currentBlendDstAlpha = blendDstAlpha;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
currentBlendEquation = null;
|
|
currentBlendSrc = null;
|
|
currentBlendDst = null;
|
|
currentBlendEquationAlpha = null;
|
|
currentBlendSrcAlpha = null;
|
|
currentBlendDstAlpha = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setMaterial( material ) {
|
|
|
|
material.side === DoubleSide
|
|
? disable( gl.CULL_FACE )
|
|
: enable( gl.CULL_FACE );
|
|
|
|
setFlipSided( material.side === BackSide );
|
|
|
|
material.transparent === true
|
|
? setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
|
|
: setBlending( NoBlending );
|
|
|
|
depthBuffer.setFunc( material.depthFunc );
|
|
depthBuffer.setTest( material.depthTest );
|
|
depthBuffer.setMask( material.depthWrite );
|
|
colorBuffer.setMask( material.colorWrite );
|
|
|
|
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function setFlipSided( flipSided ) {
|
|
|
|
if ( currentFlipSided !== flipSided ) {
|
|
|
|
if ( flipSided ) {
|
|
|
|
gl.frontFace( gl.CW );
|
|
|
|
} else {
|
|
|
|
gl.frontFace( gl.CCW );
|
|
|
|
}
|
|
|
|
currentFlipSided = flipSided;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setCullFace( cullFace ) {
|
|
|
|
if ( cullFace !== CullFaceNone ) {
|
|
|
|
enable( gl.CULL_FACE );
|
|
|
|
if ( cullFace !== currentCullFace ) {
|
|
|
|
if ( cullFace === CullFaceBack ) {
|
|
|
|
gl.cullFace( gl.BACK );
|
|
|
|
} else if ( cullFace === CullFaceFront ) {
|
|
|
|
gl.cullFace( gl.FRONT );
|
|
|
|
} else {
|
|
|
|
gl.cullFace( gl.FRONT_AND_BACK );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
disable( gl.CULL_FACE );
|
|
|
|
}
|
|
|
|
currentCullFace = cullFace;
|
|
|
|
}
|
|
|
|
function setLineWidth( width ) {
|
|
|
|
if ( width !== currentLineWidth ) {
|
|
|
|
if ( lineWidthAvailable ) gl.lineWidth( width );
|
|
|
|
currentLineWidth = width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setPolygonOffset( polygonOffset, factor, units ) {
|
|
|
|
if ( polygonOffset ) {
|
|
|
|
enable( gl.POLYGON_OFFSET_FILL );
|
|
|
|
if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
|
|
|
|
gl.polygonOffset( factor, units );
|
|
|
|
currentPolygonOffsetFactor = factor;
|
|
currentPolygonOffsetUnits = units;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
disable( gl.POLYGON_OFFSET_FILL );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function getScissorTest() {
|
|
|
|
return currentScissorTest;
|
|
|
|
}
|
|
|
|
function setScissorTest( scissorTest ) {
|
|
|
|
currentScissorTest = scissorTest;
|
|
|
|
if ( scissorTest ) {
|
|
|
|
enable( gl.SCISSOR_TEST );
|
|
|
|
} else {
|
|
|
|
disable( gl.SCISSOR_TEST );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// texture
|
|
|
|
function activeTexture( webglSlot ) {
|
|
|
|
if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
|
|
|
|
if ( currentTextureSlot !== webglSlot ) {
|
|
|
|
gl.activeTexture( webglSlot );
|
|
currentTextureSlot = webglSlot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function bindTexture( webglType, webglTexture ) {
|
|
|
|
if ( currentTextureSlot === null ) {
|
|
|
|
activeTexture();
|
|
|
|
}
|
|
|
|
var boundTexture = currentBoundTextures[ currentTextureSlot ];
|
|
|
|
if ( boundTexture === undefined ) {
|
|
|
|
boundTexture = { type: undefined, texture: undefined };
|
|
currentBoundTextures[ currentTextureSlot ] = boundTexture;
|
|
|
|
}
|
|
|
|
if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
|
|
|
|
gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
|
|
|
|
boundTexture.type = webglType;
|
|
boundTexture.texture = webglTexture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function compressedTexImage2D() {
|
|
|
|
try {
|
|
|
|
gl.compressedTexImage2D.apply( gl, arguments );
|
|
|
|
} catch ( error ) {
|
|
|
|
console.error( error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function texImage2D() {
|
|
|
|
try {
|
|
|
|
gl.texImage2D.apply( gl, arguments );
|
|
|
|
} catch ( error ) {
|
|
|
|
console.error( error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function scissor( scissor ) {
|
|
|
|
if ( currentScissor.equals( scissor ) === false ) {
|
|
|
|
gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
|
|
currentScissor.copy( scissor );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function viewport( viewport ) {
|
|
|
|
if ( currentViewport.equals( viewport ) === false ) {
|
|
|
|
gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
|
|
currentViewport.copy( viewport );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function reset() {
|
|
|
|
for ( var i = 0; i < enabledAttributes.length; i ++ ) {
|
|
|
|
if ( enabledAttributes[ i ] === 1 ) {
|
|
|
|
gl.disableVertexAttribArray( i );
|
|
enabledAttributes[ i ] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
capabilities = {};
|
|
|
|
compressedTextureFormats = null;
|
|
|
|
currentTextureSlot = null;
|
|
currentBoundTextures = {};
|
|
|
|
currentBlending = null;
|
|
|
|
currentFlipSided = null;
|
|
currentCullFace = null;
|
|
|
|
colorBuffer.reset();
|
|
depthBuffer.reset();
|
|
stencilBuffer.reset();
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
buffers: {
|
|
color: colorBuffer,
|
|
depth: depthBuffer,
|
|
stencil: stencilBuffer
|
|
},
|
|
|
|
init: init,
|
|
initAttributes: initAttributes,
|
|
enableAttribute: enableAttribute,
|
|
enableAttributeAndDivisor: enableAttributeAndDivisor,
|
|
disableUnusedAttributes: disableUnusedAttributes,
|
|
enable: enable,
|
|
disable: disable,
|
|
getCompressedTextureFormats: getCompressedTextureFormats,
|
|
|
|
setBlending: setBlending,
|
|
setMaterial: setMaterial,
|
|
|
|
setFlipSided: setFlipSided,
|
|
setCullFace: setCullFace,
|
|
|
|
setLineWidth: setLineWidth,
|
|
setPolygonOffset: setPolygonOffset,
|
|
|
|
getScissorTest: getScissorTest,
|
|
setScissorTest: setScissorTest,
|
|
|
|
activeTexture: activeTexture,
|
|
bindTexture: bindTexture,
|
|
compressedTexImage2D: compressedTexImage2D,
|
|
texImage2D: texImage2D,
|
|
|
|
scissor: scissor,
|
|
viewport: viewport,
|
|
|
|
reset: reset
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLCapabilities( gl, extensions, parameters ) {
|
|
|
|
var maxAnisotropy;
|
|
|
|
function getMaxAnisotropy() {
|
|
|
|
if ( maxAnisotropy !== undefined ) return maxAnisotropy;
|
|
|
|
var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
|
|
|
|
if ( extension !== null ) {
|
|
|
|
maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
|
|
|
|
} else {
|
|
|
|
maxAnisotropy = 0;
|
|
|
|
}
|
|
|
|
return maxAnisotropy;
|
|
|
|
}
|
|
|
|
function getMaxPrecision( precision ) {
|
|
|
|
if ( precision === 'highp' ) {
|
|
|
|
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
|
|
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
|
|
|
|
return 'highp';
|
|
|
|
}
|
|
|
|
precision = 'mediump';
|
|
|
|
}
|
|
|
|
if ( precision === 'mediump' ) {
|
|
|
|
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
|
|
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
|
|
|
|
return 'mediump';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 'lowp';
|
|
|
|
}
|
|
|
|
var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
|
|
var maxPrecision = getMaxPrecision( precision );
|
|
|
|
if ( maxPrecision !== precision ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
|
|
precision = maxPrecision;
|
|
|
|
}
|
|
|
|
var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );
|
|
|
|
var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
|
|
var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
|
|
var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
|
|
var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
|
|
|
|
var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
|
|
var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
|
|
var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
|
|
var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
|
|
|
|
var vertexTextures = maxVertexTextures > 0;
|
|
var floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
|
|
var floatVertexTextures = vertexTextures && floatFragmentTextures;
|
|
|
|
return {
|
|
|
|
getMaxAnisotropy: getMaxAnisotropy,
|
|
getMaxPrecision: getMaxPrecision,
|
|
|
|
precision: precision,
|
|
logarithmicDepthBuffer: logarithmicDepthBuffer,
|
|
|
|
maxTextures: maxTextures,
|
|
maxVertexTextures: maxVertexTextures,
|
|
maxTextureSize: maxTextureSize,
|
|
maxCubemapSize: maxCubemapSize,
|
|
|
|
maxAttributes: maxAttributes,
|
|
maxVertexUniforms: maxVertexUniforms,
|
|
maxVaryings: maxVaryings,
|
|
maxFragmentUniforms: maxFragmentUniforms,
|
|
|
|
vertexTextures: vertexTextures,
|
|
floatFragmentTextures: floatFragmentTextures,
|
|
floatVertexTextures: floatVertexTextures
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function WebGLExtensions( gl ) {
|
|
|
|
var extensions = {};
|
|
|
|
return {
|
|
|
|
get: function ( name ) {
|
|
|
|
if ( extensions[ name ] !== undefined ) {
|
|
|
|
return extensions[ name ];
|
|
|
|
}
|
|
|
|
var extension;
|
|
|
|
switch ( name ) {
|
|
|
|
case 'WEBGL_depth_texture':
|
|
extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
|
|
break;
|
|
|
|
case 'EXT_texture_filter_anisotropic':
|
|
extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
|
|
break;
|
|
|
|
case 'WEBGL_compressed_texture_s3tc':
|
|
extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
|
|
break;
|
|
|
|
case 'WEBGL_compressed_texture_pvrtc':
|
|
extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
|
|
break;
|
|
|
|
case 'WEBGL_compressed_texture_etc1':
|
|
extension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );
|
|
break;
|
|
|
|
default:
|
|
extension = gl.getExtension( name );
|
|
|
|
}
|
|
|
|
if ( extension === null ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
|
|
|
|
}
|
|
|
|
extensions[ name ] = extension;
|
|
|
|
return extension;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* @author tschw
|
|
*/
|
|
|
|
function WebGLClipping() {
|
|
|
|
var scope = this,
|
|
|
|
globalState = null,
|
|
numGlobalPlanes = 0,
|
|
localClippingEnabled = false,
|
|
renderingShadows = false,
|
|
|
|
plane = new Plane(),
|
|
viewNormalMatrix = new Matrix3(),
|
|
|
|
uniform = { value: null, needsUpdate: false };
|
|
|
|
this.uniform = uniform;
|
|
this.numPlanes = 0;
|
|
this.numIntersection = 0;
|
|
|
|
this.init = function( planes, enableLocalClipping, camera ) {
|
|
|
|
var enabled =
|
|
planes.length !== 0 ||
|
|
enableLocalClipping ||
|
|
// enable state of previous frame - the clipping code has to
|
|
// run another frame in order to reset the state:
|
|
numGlobalPlanes !== 0 ||
|
|
localClippingEnabled;
|
|
|
|
localClippingEnabled = enableLocalClipping;
|
|
|
|
globalState = projectPlanes( planes, camera, 0 );
|
|
numGlobalPlanes = planes.length;
|
|
|
|
return enabled;
|
|
|
|
};
|
|
|
|
this.beginShadows = function() {
|
|
|
|
renderingShadows = true;
|
|
projectPlanes( null );
|
|
|
|
};
|
|
|
|
this.endShadows = function() {
|
|
|
|
renderingShadows = false;
|
|
resetGlobalState();
|
|
|
|
};
|
|
|
|
this.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {
|
|
|
|
if ( ! localClippingEnabled ||
|
|
planes === null || planes.length === 0 ||
|
|
renderingShadows && ! clipShadows ) {
|
|
// there's no local clipping
|
|
|
|
if ( renderingShadows ) {
|
|
// there's no global clipping
|
|
|
|
projectPlanes( null );
|
|
|
|
} else {
|
|
|
|
resetGlobalState();
|
|
}
|
|
|
|
} else {
|
|
|
|
var nGlobal = renderingShadows ? 0 : numGlobalPlanes,
|
|
lGlobal = nGlobal * 4,
|
|
|
|
dstArray = cache.clippingState || null;
|
|
|
|
uniform.value = dstArray; // ensure unique state
|
|
|
|
dstArray = projectPlanes( planes, camera, lGlobal, fromCache );
|
|
|
|
for ( var i = 0; i !== lGlobal; ++ i ) {
|
|
|
|
dstArray[ i ] = globalState[ i ];
|
|
|
|
}
|
|
|
|
cache.clippingState = dstArray;
|
|
this.numIntersection = clipIntersection ? this.numPlanes : 0;
|
|
this.numPlanes += nGlobal;
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
function resetGlobalState() {
|
|
|
|
if ( uniform.value !== globalState ) {
|
|
|
|
uniform.value = globalState;
|
|
uniform.needsUpdate = numGlobalPlanes > 0;
|
|
|
|
}
|
|
|
|
scope.numPlanes = numGlobalPlanes;
|
|
scope.numIntersection = 0;
|
|
|
|
}
|
|
|
|
function projectPlanes( planes, camera, dstOffset, skipTransform ) {
|
|
|
|
var nPlanes = planes !== null ? planes.length : 0,
|
|
dstArray = null;
|
|
|
|
if ( nPlanes !== 0 ) {
|
|
|
|
dstArray = uniform.value;
|
|
|
|
if ( skipTransform !== true || dstArray === null ) {
|
|
|
|
var flatSize = dstOffset + nPlanes * 4,
|
|
viewMatrix = camera.matrixWorldInverse;
|
|
|
|
viewNormalMatrix.getNormalMatrix( viewMatrix );
|
|
|
|
if ( dstArray === null || dstArray.length < flatSize ) {
|
|
|
|
dstArray = new Float32Array( flatSize );
|
|
|
|
}
|
|
|
|
for ( var i = 0, i4 = dstOffset;
|
|
i !== nPlanes; ++ i, i4 += 4 ) {
|
|
|
|
plane.copy( planes[ i ] ).
|
|
applyMatrix4( viewMatrix, viewNormalMatrix );
|
|
|
|
plane.normal.toArray( dstArray, i4 );
|
|
dstArray[ i4 + 3 ] = plane.constant;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uniform.value = dstArray;
|
|
uniform.needsUpdate = true;
|
|
|
|
}
|
|
|
|
scope.numPlanes = nPlanes;
|
|
|
|
return dstArray;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// import { Sphere } from '../math/Sphere';
|
|
/**
|
|
* @author supereggbert / http://www.paulbrunt.co.uk/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author szimek / https://github.com/szimek/
|
|
* @author tschw
|
|
*/
|
|
|
|
function WebGLRenderer( parameters ) {
|
|
|
|
console.log( 'THREE.WebGLRenderer', REVISION );
|
|
|
|
parameters = parameters || {};
|
|
|
|
var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
|
|
_context = parameters.context !== undefined ? parameters.context : null,
|
|
|
|
_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
|
|
_depth = parameters.depth !== undefined ? parameters.depth : true,
|
|
_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
|
|
_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
|
|
_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
|
|
_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
|
|
|
|
var lights = [];
|
|
|
|
var currentRenderList = null;
|
|
|
|
var morphInfluences = new Float32Array( 8 );
|
|
|
|
var sprites = [];
|
|
var lensFlares = [];
|
|
|
|
// public properties
|
|
|
|
this.domElement = _canvas;
|
|
this.context = null;
|
|
|
|
// clearing
|
|
|
|
this.autoClear = true;
|
|
this.autoClearColor = true;
|
|
this.autoClearDepth = true;
|
|
this.autoClearStencil = true;
|
|
|
|
// scene graph
|
|
|
|
this.sortObjects = true;
|
|
|
|
// user-defined clipping
|
|
|
|
this.clippingPlanes = [];
|
|
this.localClippingEnabled = false;
|
|
|
|
// physically based shading
|
|
|
|
this.gammaFactor = 2.0; // for backwards compatibility
|
|
this.gammaInput = false;
|
|
this.gammaOutput = false;
|
|
|
|
// physical lights
|
|
|
|
this.physicallyCorrectLights = false;
|
|
|
|
// tone mapping
|
|
|
|
this.toneMapping = LinearToneMapping;
|
|
this.toneMappingExposure = 1.0;
|
|
this.toneMappingWhitePoint = 1.0;
|
|
|
|
// morphs
|
|
|
|
this.maxMorphTargets = 8;
|
|
this.maxMorphNormals = 4;
|
|
|
|
// internal properties
|
|
|
|
var _this = this,
|
|
|
|
// internal state cache
|
|
|
|
_currentProgram = null,
|
|
_currentRenderTarget = null,
|
|
_currentFramebuffer = null,
|
|
_currentMaterialId = - 1,
|
|
_currentGeometryProgram = '',
|
|
_currentCamera = null,
|
|
|
|
_currentScissor = new Vector4(),
|
|
_currentScissorTest = null,
|
|
|
|
_currentViewport = new Vector4(),
|
|
|
|
//
|
|
|
|
_usedTextureUnits = 0,
|
|
|
|
//
|
|
|
|
_clearColor = new Color( 0x000000 ),
|
|
_clearAlpha = 0,
|
|
|
|
_width = _canvas.width,
|
|
_height = _canvas.height,
|
|
|
|
_pixelRatio = 1,
|
|
|
|
_scissor = new Vector4( 0, 0, _width, _height ),
|
|
_scissorTest = false,
|
|
|
|
_viewport = new Vector4( 0, 0, _width, _height ),
|
|
|
|
// frustum
|
|
|
|
_frustum = new Frustum(),
|
|
|
|
// clipping
|
|
|
|
_clipping = new WebGLClipping(),
|
|
_clippingEnabled = false,
|
|
_localClippingEnabled = false,
|
|
|
|
// camera matrices cache
|
|
|
|
_projScreenMatrix = new Matrix4(),
|
|
|
|
_vector3 = new Vector3(),
|
|
_matrix4 = new Matrix4(),
|
|
_matrix42 = new Matrix4(),
|
|
|
|
// light arrays cache
|
|
|
|
_lights = {
|
|
|
|
hash: '',
|
|
|
|
ambient: [ 0, 0, 0 ],
|
|
directional: [],
|
|
directionalShadowMap: [],
|
|
directionalShadowMatrix: [],
|
|
spot: [],
|
|
spotShadowMap: [],
|
|
spotShadowMatrix: [],
|
|
rectArea: [],
|
|
point: [],
|
|
pointShadowMap: [],
|
|
pointShadowMatrix: [],
|
|
hemi: [],
|
|
|
|
shadows: []
|
|
|
|
},
|
|
|
|
// info
|
|
|
|
_infoMemory = {
|
|
geometries: 0,
|
|
textures: 0
|
|
},
|
|
|
|
_infoRender = {
|
|
|
|
frame: 0,
|
|
calls: 0,
|
|
vertices: 0,
|
|
faces: 0,
|
|
points: 0
|
|
|
|
};
|
|
|
|
this.info = {
|
|
|
|
render: _infoRender,
|
|
memory: _infoMemory,
|
|
programs: null
|
|
|
|
};
|
|
|
|
|
|
// initialize
|
|
|
|
var _gl;
|
|
|
|
try {
|
|
|
|
var contextAttributes = {
|
|
alpha: _alpha,
|
|
depth: _depth,
|
|
stencil: _stencil,
|
|
antialias: _antialias,
|
|
premultipliedAlpha: _premultipliedAlpha,
|
|
preserveDrawingBuffer: _preserveDrawingBuffer
|
|
};
|
|
|
|
_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
|
|
|
|
if ( _gl === null ) {
|
|
|
|
if ( _canvas.getContext( 'webgl' ) !== null ) {
|
|
|
|
throw 'Error creating WebGL context with your selected attributes.';
|
|
|
|
} else {
|
|
|
|
throw 'Error creating WebGL context.';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Some experimental-webgl implementations do not have getShaderPrecisionFormat
|
|
|
|
if ( _gl.getShaderPrecisionFormat === undefined ) {
|
|
|
|
_gl.getShaderPrecisionFormat = function () {
|
|
|
|
return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
|
|
|
|
};
|
|
|
|
}
|
|
|
|
_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
|
|
|
|
} catch ( error ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer: ' + error );
|
|
|
|
}
|
|
|
|
var extensions = new WebGLExtensions( _gl );
|
|
|
|
extensions.get( 'WEBGL_depth_texture' );
|
|
extensions.get( 'OES_texture_float' );
|
|
extensions.get( 'OES_texture_float_linear' );
|
|
extensions.get( 'OES_texture_half_float' );
|
|
extensions.get( 'OES_texture_half_float_linear' );
|
|
extensions.get( 'OES_standard_derivatives' );
|
|
extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
if ( extensions.get( 'OES_element_index_uint' ) ) {
|
|
|
|
BufferGeometry.MaxIndex = 4294967296;
|
|
|
|
}
|
|
|
|
var capabilities = new WebGLCapabilities( _gl, extensions, parameters );
|
|
|
|
var state = new WebGLState( _gl, extensions, paramThreeToGL );
|
|
|
|
var properties = new WebGLProperties();
|
|
var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory );
|
|
var attributes = new WebGLAttributes( _gl );
|
|
var geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
|
|
var objects = new WebGLObjects( _gl, geometries, _infoRender );
|
|
var programCache = new WebGLPrograms( this, capabilities );
|
|
var lightCache = new WebGLLights();
|
|
var renderLists = new WebGLRenderLists();
|
|
|
|
this.info.programs = programCache.programs;
|
|
|
|
var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
|
|
var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
|
|
|
|
//
|
|
|
|
var backgroundPlaneCamera, backgroundPlaneMesh;
|
|
var backgroundBoxCamera, backgroundBoxMesh;
|
|
|
|
//
|
|
|
|
function getTargetPixelRatio() {
|
|
|
|
return _currentRenderTarget === null ? _pixelRatio : 1;
|
|
|
|
}
|
|
|
|
function setDefaultGLState() {
|
|
|
|
state.init();
|
|
|
|
state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
|
|
state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
|
|
|
|
state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
|
|
|
|
}
|
|
|
|
function resetGLState() {
|
|
|
|
_currentProgram = null;
|
|
_currentCamera = null;
|
|
|
|
_currentGeometryProgram = '';
|
|
_currentMaterialId = - 1;
|
|
|
|
state.reset();
|
|
|
|
}
|
|
|
|
setDefaultGLState();
|
|
|
|
this.context = _gl;
|
|
this.capabilities = capabilities;
|
|
this.extensions = extensions;
|
|
this.properties = properties;
|
|
this.state = state;
|
|
|
|
// shadow map
|
|
|
|
var shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );
|
|
|
|
this.shadowMap = shadowMap;
|
|
|
|
|
|
// Plugins
|
|
|
|
var spritePlugin = new SpritePlugin( this, sprites );
|
|
var lensFlarePlugin = new LensFlarePlugin( this, lensFlares );
|
|
|
|
// API
|
|
|
|
this.getContext = function () {
|
|
|
|
return _gl;
|
|
|
|
};
|
|
|
|
this.getContextAttributes = function () {
|
|
|
|
return _gl.getContextAttributes();
|
|
|
|
};
|
|
|
|
this.forceContextLoss = function () {
|
|
|
|
var extension = extensions.get( 'WEBGL_lose_context' );
|
|
if ( extension ) extension.loseContext();
|
|
|
|
};
|
|
|
|
this.getMaxAnisotropy = function () {
|
|
|
|
return capabilities.getMaxAnisotropy();
|
|
|
|
};
|
|
|
|
this.getPrecision = function () {
|
|
|
|
return capabilities.precision;
|
|
|
|
};
|
|
|
|
this.getPixelRatio = function () {
|
|
|
|
return _pixelRatio;
|
|
|
|
};
|
|
|
|
this.setPixelRatio = function ( value ) {
|
|
|
|
if ( value === undefined ) return;
|
|
|
|
_pixelRatio = value;
|
|
|
|
this.setSize( _viewport.z, _viewport.w, false );
|
|
|
|
};
|
|
|
|
this.getSize = function () {
|
|
|
|
return {
|
|
width: _width,
|
|
height: _height
|
|
};
|
|
|
|
};
|
|
|
|
this.setSize = function ( width, height, updateStyle ) {
|
|
|
|
_width = width;
|
|
_height = height;
|
|
|
|
_canvas.width = width * _pixelRatio;
|
|
_canvas.height = height * _pixelRatio;
|
|
|
|
if ( updateStyle !== false ) {
|
|
|
|
_canvas.style.width = width + 'px';
|
|
_canvas.style.height = height + 'px';
|
|
|
|
}
|
|
|
|
this.setViewport( 0, 0, width, height );
|
|
|
|
};
|
|
|
|
this.setViewport = function ( x, y, width, height ) {
|
|
|
|
state.viewport( _viewport.set( x, y, width, height ) );
|
|
|
|
};
|
|
|
|
this.setScissor = function ( x, y, width, height ) {
|
|
|
|
state.scissor( _scissor.set( x, y, width, height ) );
|
|
|
|
};
|
|
|
|
this.setScissorTest = function ( boolean ) {
|
|
|
|
state.setScissorTest( _scissorTest = boolean );
|
|
|
|
};
|
|
|
|
// Clearing
|
|
|
|
this.getClearColor = function () {
|
|
|
|
return _clearColor;
|
|
|
|
};
|
|
|
|
this.setClearColor = function ( color, alpha ) {
|
|
|
|
_clearColor.set( color );
|
|
|
|
_clearAlpha = alpha !== undefined ? alpha : 1;
|
|
|
|
state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
|
|
|
|
};
|
|
|
|
this.getClearAlpha = function () {
|
|
|
|
return _clearAlpha;
|
|
|
|
};
|
|
|
|
this.setClearAlpha = function ( alpha ) {
|
|
|
|
_clearAlpha = alpha;
|
|
|
|
state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
|
|
|
|
};
|
|
|
|
this.clear = function ( color, depth, stencil ) {
|
|
|
|
var bits = 0;
|
|
|
|
if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
|
|
if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
|
|
if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
|
|
|
|
_gl.clear( bits );
|
|
|
|
};
|
|
|
|
this.clearColor = function () {
|
|
|
|
this.clear( true, false, false );
|
|
|
|
};
|
|
|
|
this.clearDepth = function () {
|
|
|
|
this.clear( false, true, false );
|
|
|
|
};
|
|
|
|
this.clearStencil = function () {
|
|
|
|
this.clear( false, false, true );
|
|
|
|
};
|
|
|
|
this.clearTarget = function ( renderTarget, color, depth, stencil ) {
|
|
|
|
this.setRenderTarget( renderTarget );
|
|
this.clear( color, depth, stencil );
|
|
|
|
};
|
|
|
|
// Reset
|
|
|
|
this.resetGLState = resetGLState;
|
|
|
|
this.dispose = function () {
|
|
|
|
_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
|
|
|
|
renderLists.dispose();
|
|
|
|
};
|
|
|
|
// Events
|
|
|
|
function onContextLost( event ) {
|
|
|
|
event.preventDefault();
|
|
|
|
resetGLState();
|
|
setDefaultGLState();
|
|
|
|
properties.clear();
|
|
objects.clear();
|
|
|
|
}
|
|
|
|
function onMaterialDispose( event ) {
|
|
|
|
var material = event.target;
|
|
|
|
material.removeEventListener( 'dispose', onMaterialDispose );
|
|
|
|
deallocateMaterial( material );
|
|
|
|
}
|
|
|
|
// Buffer deallocation
|
|
|
|
function deallocateMaterial( material ) {
|
|
|
|
releaseMaterialProgramReference( material );
|
|
|
|
properties.remove( material );
|
|
|
|
}
|
|
|
|
|
|
function releaseMaterialProgramReference( material ) {
|
|
|
|
var programInfo = properties.get( material ).program;
|
|
|
|
material.program = undefined;
|
|
|
|
if ( programInfo !== undefined ) {
|
|
|
|
programCache.releaseProgram( programInfo );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Buffer rendering
|
|
|
|
function renderObjectImmediate( object, program, material ) {
|
|
|
|
object.render( function ( object ) {
|
|
|
|
_this.renderBufferImmediate( object, program, material );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
this.renderBufferImmediate = function ( object, program, material ) {
|
|
|
|
state.initAttributes();
|
|
|
|
var buffers = properties.get( object );
|
|
|
|
if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
|
|
if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
|
|
if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
|
|
if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
|
|
|
|
var programAttributes = program.getAttributes();
|
|
|
|
if ( object.hasPositions ) {
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
|
|
|
|
state.enableAttribute( programAttributes.position );
|
|
_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
}
|
|
|
|
if ( object.hasNormals ) {
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
|
|
|
|
if ( ! material.isMeshPhongMaterial &&
|
|
! material.isMeshStandardMaterial &&
|
|
! material.isMeshNormalMaterial &&
|
|
material.shading === FlatShading ) {
|
|
|
|
for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
|
|
|
|
var array = object.normalArray;
|
|
|
|
var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
|
|
var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
|
|
var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
|
|
|
|
array[ i + 0 ] = nx;
|
|
array[ i + 1 ] = ny;
|
|
array[ i + 2 ] = nz;
|
|
|
|
array[ i + 3 ] = nx;
|
|
array[ i + 4 ] = ny;
|
|
array[ i + 5 ] = nz;
|
|
|
|
array[ i + 6 ] = nx;
|
|
array[ i + 7 ] = ny;
|
|
array[ i + 8 ] = nz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
|
|
|
|
state.enableAttribute( programAttributes.normal );
|
|
|
|
_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
}
|
|
|
|
if ( object.hasUvs && material.map ) {
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
|
|
|
|
state.enableAttribute( programAttributes.uv );
|
|
|
|
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
|
|
|
|
}
|
|
|
|
if ( object.hasColors && material.vertexColors !== NoColors ) {
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
|
|
|
|
state.enableAttribute( programAttributes.color );
|
|
|
|
_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
}
|
|
|
|
state.disableUnusedAttributes();
|
|
|
|
_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
|
|
|
|
object.count = 0;
|
|
|
|
};
|
|
|
|
function absNumericalSort( a, b ) {
|
|
|
|
return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
|
|
|
|
}
|
|
|
|
this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
|
|
|
|
state.setMaterial( material );
|
|
|
|
var program = setProgram( camera, fog, material, object );
|
|
var geometryProgram = geometry.id + '_' + program.id + '_' + ( material.wireframe === true );
|
|
|
|
var updateBuffers = false;
|
|
|
|
if ( geometryProgram !== _currentGeometryProgram ) {
|
|
|
|
_currentGeometryProgram = geometryProgram;
|
|
updateBuffers = true;
|
|
|
|
}
|
|
|
|
// morph targets
|
|
|
|
var morphTargetInfluences = object.morphTargetInfluences;
|
|
|
|
if ( morphTargetInfluences !== undefined ) {
|
|
|
|
// TODO Remove allocations
|
|
|
|
var activeInfluences = [];
|
|
|
|
for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
|
|
|
|
var influence = morphTargetInfluences[ i ];
|
|
activeInfluences.push( [ influence, i ] );
|
|
|
|
}
|
|
|
|
activeInfluences.sort( absNumericalSort );
|
|
|
|
if ( activeInfluences.length > 8 ) {
|
|
|
|
activeInfluences.length = 8;
|
|
|
|
}
|
|
|
|
var morphAttributes = geometry.morphAttributes;
|
|
|
|
for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
|
|
|
|
var influence = activeInfluences[ i ];
|
|
morphInfluences[ i ] = influence[ 0 ];
|
|
|
|
if ( influence[ 0 ] !== 0 ) {
|
|
|
|
var index = influence[ 1 ];
|
|
|
|
if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
|
|
if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
|
|
|
|
} else {
|
|
|
|
if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
|
|
if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
|
|
|
|
morphInfluences[ i ] = 0.0;
|
|
|
|
}
|
|
|
|
program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
|
|
|
|
updateBuffers = true;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var index = geometry.index;
|
|
var position = geometry.attributes.position;
|
|
var rangeFactor = 1;
|
|
|
|
if ( material.wireframe === true ) {
|
|
|
|
index = geometries.getWireframeAttribute( geometry );
|
|
rangeFactor = 2;
|
|
|
|
}
|
|
|
|
var renderer = bufferRenderer;
|
|
|
|
if ( index !== null ) {
|
|
|
|
renderer = indexedBufferRenderer;
|
|
renderer.setIndex( index );
|
|
|
|
}
|
|
|
|
if ( updateBuffers ) {
|
|
|
|
setupVertexAttributes( material, program, geometry );
|
|
|
|
if ( index !== null ) {
|
|
|
|
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attributes.get( index ).buffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var dataCount = 0;
|
|
|
|
if ( index !== null ) {
|
|
|
|
dataCount = index.count;
|
|
|
|
} else if ( position !== undefined ) {
|
|
|
|
dataCount = position.count;
|
|
|
|
}
|
|
|
|
var rangeStart = geometry.drawRange.start * rangeFactor;
|
|
var rangeCount = geometry.drawRange.count * rangeFactor;
|
|
|
|
var groupStart = group !== null ? group.start * rangeFactor : 0;
|
|
var groupCount = group !== null ? group.count * rangeFactor : Infinity;
|
|
|
|
var drawStart = Math.max( rangeStart, groupStart );
|
|
var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
|
|
|
|
var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
|
|
|
|
if ( drawCount === 0 ) return;
|
|
|
|
//
|
|
|
|
if ( object.isMesh ) {
|
|
|
|
if ( material.wireframe === true ) {
|
|
|
|
state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
|
|
renderer.setMode( _gl.LINES );
|
|
|
|
} else {
|
|
|
|
switch ( object.drawMode ) {
|
|
|
|
case TrianglesDrawMode:
|
|
renderer.setMode( _gl.TRIANGLES );
|
|
break;
|
|
|
|
case TriangleStripDrawMode:
|
|
renderer.setMode( _gl.TRIANGLE_STRIP );
|
|
break;
|
|
|
|
case TriangleFanDrawMode:
|
|
renderer.setMode( _gl.TRIANGLE_FAN );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} else if ( object.isLine ) {
|
|
|
|
var lineWidth = material.linewidth;
|
|
|
|
if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
|
|
|
|
state.setLineWidth( lineWidth * getTargetPixelRatio() );
|
|
|
|
if ( object.isLineSegments ) {
|
|
|
|
renderer.setMode( _gl.LINES );
|
|
|
|
} else if ( object.isLineLoop ) {
|
|
|
|
renderer.setMode( _gl.LINE_LOOP );
|
|
|
|
} else {
|
|
|
|
renderer.setMode( _gl.LINE_STRIP );
|
|
|
|
}
|
|
|
|
} else if ( object.isPoints ) {
|
|
|
|
renderer.setMode( _gl.POINTS );
|
|
|
|
}
|
|
|
|
if ( geometry && geometry.isInstancedBufferGeometry ) {
|
|
|
|
if ( geometry.maxInstancedCount > 0 ) {
|
|
|
|
renderer.renderInstances( geometry, drawStart, drawCount );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
renderer.render( drawStart, drawCount );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
function setupVertexAttributes( material, program, geometry, startIndex ) {
|
|
|
|
if ( geometry && geometry.isInstancedBufferGeometry ) {
|
|
|
|
if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( startIndex === undefined ) startIndex = 0;
|
|
|
|
state.initAttributes();
|
|
|
|
var geometryAttributes = geometry.attributes;
|
|
|
|
var programAttributes = program.getAttributes();
|
|
|
|
var materialDefaultAttributeValues = material.defaultAttributeValues;
|
|
|
|
for ( var name in programAttributes ) {
|
|
|
|
var programAttribute = programAttributes[ name ];
|
|
|
|
if ( programAttribute >= 0 ) {
|
|
|
|
var geometryAttribute = geometryAttributes[ name ];
|
|
|
|
if ( geometryAttribute !== undefined ) {
|
|
|
|
var normalized = geometryAttribute.normalized;
|
|
var size = geometryAttribute.itemSize;
|
|
|
|
var attributeProperties = attributes.get( geometryAttribute );
|
|
|
|
var buffer = attributeProperties.buffer;
|
|
var type = attributeProperties.type;
|
|
var bytesPerElement = attributeProperties.bytesPerElement;
|
|
|
|
if ( geometryAttribute.isInterleavedBufferAttribute ) {
|
|
|
|
var data = geometryAttribute.data;
|
|
var stride = data.stride;
|
|
var offset = geometryAttribute.offset;
|
|
|
|
if ( data && data.isInstancedInterleavedBuffer ) {
|
|
|
|
state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
|
|
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
|
|
geometry.maxInstancedCount = data.meshPerAttribute * data.count;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.enableAttribute( programAttribute );
|
|
|
|
}
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
|
|
|
|
} else {
|
|
|
|
if ( geometryAttribute.isInstancedBufferAttribute ) {
|
|
|
|
state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
|
|
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
|
|
geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.enableAttribute( programAttribute );
|
|
|
|
}
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
|
|
|
|
}
|
|
|
|
} else if ( materialDefaultAttributeValues !== undefined ) {
|
|
|
|
var value = materialDefaultAttributeValues[ name ];
|
|
|
|
if ( value !== undefined ) {
|
|
|
|
switch ( value.length ) {
|
|
|
|
case 2:
|
|
_gl.vertexAttrib2fv( programAttribute, value );
|
|
break;
|
|
|
|
case 3:
|
|
_gl.vertexAttrib3fv( programAttribute, value );
|
|
break;
|
|
|
|
case 4:
|
|
_gl.vertexAttrib4fv( programAttribute, value );
|
|
break;
|
|
|
|
default:
|
|
_gl.vertexAttrib1fv( programAttribute, value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
state.disableUnusedAttributes();
|
|
|
|
}
|
|
|
|
// Compile
|
|
|
|
this.compile = function ( scene, camera ) {
|
|
|
|
lights = [];
|
|
|
|
scene.traverse( function ( object ) {
|
|
|
|
if ( object.isLight ) {
|
|
|
|
lights.push( object );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
setupLights( lights, camera );
|
|
|
|
scene.traverse( function ( object ) {
|
|
|
|
if ( object.material ) {
|
|
|
|
if ( Array.isArray( object.material ) ) {
|
|
|
|
for ( var i = 0; i < object.material.length; i ++ ) {
|
|
|
|
initMaterial( object.material[ i ], scene.fog, object );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initMaterial( object.material, scene.fog, object );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
// Rendering
|
|
|
|
this.render = function ( scene, camera, renderTarget, forceClear ) {
|
|
|
|
if ( camera !== undefined && camera.isCamera !== true ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
|
|
return;
|
|
|
|
}
|
|
|
|
// reset caching for this frame
|
|
|
|
_currentGeometryProgram = '';
|
|
_currentMaterialId = - 1;
|
|
_currentCamera = null;
|
|
|
|
// update scene graph
|
|
|
|
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
|
|
|
|
// update camera matrices and frustum
|
|
|
|
camera.onBeforeRender( _this );
|
|
|
|
if ( camera.parent === null ) camera.updateMatrixWorld();
|
|
|
|
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
|
|
|
|
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
|
|
_frustum.setFromMatrix( _projScreenMatrix );
|
|
|
|
lights.length = 0;
|
|
sprites.length = 0;
|
|
lensFlares.length = 0;
|
|
|
|
_localClippingEnabled = this.localClippingEnabled;
|
|
_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
|
|
|
|
currentRenderList = renderLists.get( scene, camera );
|
|
currentRenderList.init();
|
|
|
|
projectObject( scene, camera, _this.sortObjects );
|
|
|
|
currentRenderList.finish();
|
|
|
|
if ( _this.sortObjects === true ) {
|
|
|
|
currentRenderList.sort();
|
|
|
|
}
|
|
|
|
//
|
|
|
|
if ( _clippingEnabled ) _clipping.beginShadows();
|
|
|
|
setupShadows( lights );
|
|
|
|
shadowMap.render( scene, camera );
|
|
|
|
setupLights( lights, camera );
|
|
|
|
if ( _clippingEnabled ) _clipping.endShadows();
|
|
|
|
//
|
|
|
|
_infoRender.frame ++;
|
|
_infoRender.calls = 0;
|
|
_infoRender.vertices = 0;
|
|
_infoRender.faces = 0;
|
|
_infoRender.points = 0;
|
|
|
|
if ( renderTarget === undefined ) {
|
|
|
|
renderTarget = null;
|
|
|
|
}
|
|
|
|
this.setRenderTarget( renderTarget );
|
|
|
|
//
|
|
|
|
var background = scene.background;
|
|
|
|
if ( background === null ) {
|
|
|
|
state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
|
|
|
|
} else if ( background && background.isColor ) {
|
|
|
|
state.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );
|
|
forceClear = true;
|
|
|
|
}
|
|
|
|
if ( this.autoClear || forceClear ) {
|
|
|
|
this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
|
|
|
|
}
|
|
|
|
if ( background && background.isCubeTexture ) {
|
|
|
|
if ( backgroundBoxCamera === undefined ) {
|
|
|
|
backgroundBoxCamera = new PerspectiveCamera();
|
|
|
|
backgroundBoxMesh = new Mesh(
|
|
new BoxBufferGeometry( 5, 5, 5 ),
|
|
new ShaderMaterial( {
|
|
uniforms: ShaderLib.cube.uniforms,
|
|
vertexShader: ShaderLib.cube.vertexShader,
|
|
fragmentShader: ShaderLib.cube.fragmentShader,
|
|
side: BackSide,
|
|
depthTest: false,
|
|
depthWrite: false,
|
|
fog: false
|
|
} )
|
|
);
|
|
|
|
}
|
|
|
|
backgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );
|
|
|
|
backgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );
|
|
backgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );
|
|
|
|
|
|
backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
|
|
backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );
|
|
|
|
objects.update( backgroundBoxMesh );
|
|
|
|
_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );
|
|
|
|
} else if ( background && background.isTexture ) {
|
|
|
|
if ( backgroundPlaneCamera === undefined ) {
|
|
|
|
backgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
|
|
|
backgroundPlaneMesh = new Mesh(
|
|
new PlaneBufferGeometry( 2, 2 ),
|
|
new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
|
|
);
|
|
|
|
}
|
|
|
|
backgroundPlaneMesh.material.map = background;
|
|
|
|
objects.update( backgroundPlaneMesh );
|
|
|
|
_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var opaqueObjects = currentRenderList.opaque;
|
|
var transparentObjects = currentRenderList.transparent;
|
|
|
|
if ( scene.overrideMaterial ) {
|
|
|
|
var overrideMaterial = scene.overrideMaterial;
|
|
|
|
if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
|
|
if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
|
|
|
|
} else {
|
|
|
|
// opaque pass (front-to-back order)
|
|
|
|
if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
|
|
|
|
// transparent pass (back-to-front order)
|
|
|
|
if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
|
|
|
|
}
|
|
|
|
// custom render plugins (post pass)
|
|
|
|
spritePlugin.render( scene, camera );
|
|
lensFlarePlugin.render( scene, camera, _currentViewport );
|
|
|
|
// Generate mipmap if we're using any kind of mipmap filtering
|
|
|
|
if ( renderTarget ) {
|
|
|
|
textures.updateRenderTargetMipmap( renderTarget );
|
|
|
|
}
|
|
|
|
// Ensure depth buffer writing is enabled so it can be cleared on next render
|
|
|
|
state.buffers.depth.setTest( true );
|
|
state.buffers.depth.setMask( true );
|
|
state.buffers.color.setMask( true );
|
|
|
|
if ( camera.isArrayCamera && camera.enabled ) {
|
|
|
|
_this.setScissorTest( false );
|
|
|
|
}
|
|
|
|
camera.onAfterRender( _this );
|
|
|
|
// _gl.finish();
|
|
|
|
};
|
|
|
|
/*
|
|
// TODO Duplicated code (Frustum)
|
|
|
|
var _sphere = new Sphere();
|
|
|
|
function isObjectViewable( object ) {
|
|
|
|
var geometry = object.geometry;
|
|
|
|
if ( geometry.boundingSphere === null )
|
|
geometry.computeBoundingSphere();
|
|
|
|
_sphere.copy( geometry.boundingSphere ).
|
|
applyMatrix4( object.matrixWorld );
|
|
|
|
return isSphereViewable( _sphere );
|
|
|
|
}
|
|
|
|
function isSpriteViewable( sprite ) {
|
|
|
|
_sphere.center.set( 0, 0, 0 );
|
|
_sphere.radius = 0.7071067811865476;
|
|
_sphere.applyMatrix4( sprite.matrixWorld );
|
|
|
|
return isSphereViewable( _sphere );
|
|
|
|
}
|
|
|
|
function isSphereViewable( sphere ) {
|
|
|
|
if ( ! _frustum.intersectsSphere( sphere ) ) return false;
|
|
|
|
var numPlanes = _clipping.numPlanes;
|
|
|
|
if ( numPlanes === 0 ) return true;
|
|
|
|
var planes = _this.clippingPlanes,
|
|
|
|
center = sphere.center,
|
|
negRad = - sphere.radius,
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
// out when deeper than radius in the negative halfspace
|
|
if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;
|
|
|
|
} while ( ++ i !== numPlanes );
|
|
|
|
return true;
|
|
|
|
}
|
|
*/
|
|
|
|
function projectObject( object, camera, sortObjects ) {
|
|
|
|
if ( ! object.visible ) return;
|
|
|
|
var visible = object.layers.test( camera.layers );
|
|
|
|
if ( visible ) {
|
|
|
|
if ( object.isLight ) {
|
|
|
|
lights.push( object );
|
|
|
|
} else if ( object.isSprite ) {
|
|
|
|
if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
|
|
|
|
sprites.push( object );
|
|
|
|
}
|
|
|
|
} else if ( object.isLensFlare ) {
|
|
|
|
lensFlares.push( object );
|
|
|
|
} else if ( object.isImmediateRenderObject ) {
|
|
|
|
if ( sortObjects ) {
|
|
|
|
_vector3.setFromMatrixPosition( object.matrixWorld )
|
|
.applyMatrix4( _projScreenMatrix );
|
|
|
|
}
|
|
|
|
currentRenderList.push( object, null, object.material, _vector3.z, null );
|
|
|
|
} else if ( object.isMesh || object.isLine || object.isPoints ) {
|
|
|
|
if ( object.isSkinnedMesh ) {
|
|
|
|
object.skeleton.update();
|
|
|
|
}
|
|
|
|
if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
|
|
|
|
if ( sortObjects ) {
|
|
|
|
_vector3.setFromMatrixPosition( object.matrixWorld )
|
|
.applyMatrix4( _projScreenMatrix );
|
|
|
|
}
|
|
|
|
var geometry = objects.update( object );
|
|
var material = object.material;
|
|
|
|
if ( Array.isArray( material ) ) {
|
|
|
|
var groups = geometry.groups;
|
|
|
|
for ( var i = 0, l = groups.length; i < l; i ++ ) {
|
|
|
|
var group = groups[ i ];
|
|
var groupMaterial = material[ group.materialIndex ];
|
|
|
|
if ( groupMaterial && groupMaterial.visible ) {
|
|
|
|
currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( material.visible ) {
|
|
|
|
currentRenderList.push( object, geometry, material, _vector3.z, null );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var children = object.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
projectObject( children[ i ], camera, sortObjects );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function renderObjects( renderList, scene, camera, overrideMaterial ) {
|
|
|
|
for ( var i = 0, l = renderList.length; i < l; i ++ ) {
|
|
|
|
var renderItem = renderList[ i ];
|
|
|
|
var object = renderItem.object;
|
|
var geometry = renderItem.geometry;
|
|
var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
|
|
var group = renderItem.group;
|
|
|
|
object.onBeforeRender( _this, scene, camera, geometry, material, group );
|
|
|
|
if ( camera.isArrayCamera && camera.enabled ) {
|
|
|
|
var cameras = camera.cameras;
|
|
|
|
for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
|
|
|
|
var camera2 = cameras[ j ];
|
|
var bounds = camera2.bounds;
|
|
|
|
_this.setViewport(
|
|
bounds.x * _width * _pixelRatio, bounds.y * _height * _pixelRatio,
|
|
bounds.z * _width * _pixelRatio, bounds.w * _height * _pixelRatio
|
|
);
|
|
_this.setScissor(
|
|
bounds.x * _width * _pixelRatio, bounds.y * _height * _pixelRatio,
|
|
bounds.z * _width * _pixelRatio, bounds.w * _height * _pixelRatio
|
|
);
|
|
_this.setScissorTest( true );
|
|
|
|
renderObject( object, scene, camera2, geometry, material, group );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
renderObject( object, scene, camera, geometry, material, group );
|
|
|
|
}
|
|
|
|
object.onAfterRender( _this, scene, camera, geometry, material, group );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function renderObject( object, scene, camera, geometry, material, group ) {
|
|
|
|
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
|
|
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
|
|
|
|
if ( object.isImmediateRenderObject ) {
|
|
|
|
state.setMaterial( material );
|
|
|
|
var program = setProgram( camera, scene.fog, material, object );
|
|
|
|
_currentGeometryProgram = '';
|
|
|
|
renderObjectImmediate( object, program, material );
|
|
|
|
} else {
|
|
|
|
_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function initMaterial( material, fog, object ) {
|
|
|
|
var materialProperties = properties.get( material );
|
|
|
|
var parameters = programCache.getParameters(
|
|
material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
|
|
|
|
var code = programCache.getProgramCode( material, parameters );
|
|
|
|
var program = materialProperties.program;
|
|
var programChange = true;
|
|
|
|
if ( program === undefined ) {
|
|
|
|
// new material
|
|
material.addEventListener( 'dispose', onMaterialDispose );
|
|
|
|
} else if ( program.code !== code ) {
|
|
|
|
// changed glsl or parameters
|
|
releaseMaterialProgramReference( material );
|
|
|
|
} else if ( parameters.shaderID !== undefined ) {
|
|
|
|
// same glsl and uniform list
|
|
return;
|
|
|
|
} else {
|
|
|
|
// only rebuild uniform list
|
|
programChange = false;
|
|
|
|
}
|
|
|
|
if ( programChange ) {
|
|
|
|
if ( parameters.shaderID ) {
|
|
|
|
var shader = ShaderLib[ parameters.shaderID ];
|
|
|
|
materialProperties.__webglShader = {
|
|
name: material.type,
|
|
uniforms: UniformsUtils.clone( shader.uniforms ),
|
|
vertexShader: shader.vertexShader,
|
|
fragmentShader: shader.fragmentShader
|
|
};
|
|
|
|
} else {
|
|
|
|
materialProperties.__webglShader = {
|
|
name: material.type,
|
|
uniforms: material.uniforms,
|
|
vertexShader: material.vertexShader,
|
|
fragmentShader: material.fragmentShader
|
|
};
|
|
|
|
}
|
|
|
|
material.__webglShader = materialProperties.__webglShader;
|
|
|
|
program = programCache.acquireProgram( material, parameters, code );
|
|
|
|
materialProperties.program = program;
|
|
material.program = program;
|
|
|
|
}
|
|
|
|
var programAttributes = program.getAttributes();
|
|
|
|
if ( material.morphTargets ) {
|
|
|
|
material.numSupportedMorphTargets = 0;
|
|
|
|
for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
|
|
|
|
if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
|
|
|
|
material.numSupportedMorphTargets ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( material.morphNormals ) {
|
|
|
|
material.numSupportedMorphNormals = 0;
|
|
|
|
for ( var i = 0; i < _this.maxMorphNormals; i ++ ) {
|
|
|
|
if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
|
|
|
|
material.numSupportedMorphNormals ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var uniforms = materialProperties.__webglShader.uniforms;
|
|
|
|
if ( ! material.isShaderMaterial &&
|
|
! material.isRawShaderMaterial ||
|
|
material.clipping === true ) {
|
|
|
|
materialProperties.numClippingPlanes = _clipping.numPlanes;
|
|
materialProperties.numIntersection = _clipping.numIntersection;
|
|
uniforms.clippingPlanes = _clipping.uniform;
|
|
|
|
}
|
|
|
|
materialProperties.fog = fog;
|
|
|
|
// store the light setup it was created for
|
|
|
|
materialProperties.lightsHash = _lights.hash;
|
|
|
|
if ( material.lights ) {
|
|
|
|
// wire up the material to this renderer's lighting state
|
|
|
|
uniforms.ambientLightColor.value = _lights.ambient;
|
|
uniforms.directionalLights.value = _lights.directional;
|
|
uniforms.spotLights.value = _lights.spot;
|
|
uniforms.rectAreaLights.value = _lights.rectArea;
|
|
uniforms.pointLights.value = _lights.point;
|
|
uniforms.hemisphereLights.value = _lights.hemi;
|
|
|
|
uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
|
|
uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
|
|
uniforms.spotShadowMap.value = _lights.spotShadowMap;
|
|
uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
|
|
uniforms.pointShadowMap.value = _lights.pointShadowMap;
|
|
uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
|
|
// TODO (abelnation): add area lights shadow info to uniforms
|
|
|
|
}
|
|
|
|
var progUniforms = materialProperties.program.getUniforms(),
|
|
uniformsList =
|
|
WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
|
|
|
|
materialProperties.uniformsList = uniformsList;
|
|
|
|
}
|
|
|
|
function setProgram( camera, fog, material, object ) {
|
|
|
|
_usedTextureUnits = 0;
|
|
|
|
var materialProperties = properties.get( material );
|
|
|
|
if ( _clippingEnabled ) {
|
|
|
|
if ( _localClippingEnabled || camera !== _currentCamera ) {
|
|
|
|
var useCache =
|
|
camera === _currentCamera &&
|
|
material.id === _currentMaterialId;
|
|
|
|
// we might want to call this function with some ClippingGroup
|
|
// object instead of the material, once it becomes feasible
|
|
// (#8465, #8379)
|
|
_clipping.setState(
|
|
material.clippingPlanes, material.clipIntersection, material.clipShadows,
|
|
camera, materialProperties, useCache );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( material.needsUpdate === false ) {
|
|
|
|
if ( materialProperties.program === undefined ) {
|
|
|
|
material.needsUpdate = true;
|
|
|
|
} else if ( material.fog && materialProperties.fog !== fog ) {
|
|
|
|
material.needsUpdate = true;
|
|
|
|
} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {
|
|
|
|
material.needsUpdate = true;
|
|
|
|
} else if ( materialProperties.numClippingPlanes !== undefined &&
|
|
( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
|
|
materialProperties.numIntersection !== _clipping.numIntersection ) ) {
|
|
|
|
material.needsUpdate = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( material.needsUpdate ) {
|
|
|
|
initMaterial( material, fog, object );
|
|
material.needsUpdate = false;
|
|
|
|
}
|
|
|
|
var refreshProgram = false;
|
|
var refreshMaterial = false;
|
|
var refreshLights = false;
|
|
|
|
var program = materialProperties.program,
|
|
p_uniforms = program.getUniforms(),
|
|
m_uniforms = materialProperties.__webglShader.uniforms;
|
|
|
|
if ( program.id !== _currentProgram ) {
|
|
|
|
_gl.useProgram( program.program );
|
|
_currentProgram = program.id;
|
|
|
|
refreshProgram = true;
|
|
refreshMaterial = true;
|
|
refreshLights = true;
|
|
|
|
}
|
|
|
|
if ( material.id !== _currentMaterialId ) {
|
|
|
|
_currentMaterialId = material.id;
|
|
|
|
refreshMaterial = true;
|
|
|
|
}
|
|
|
|
if ( refreshProgram || camera !== _currentCamera ) {
|
|
|
|
p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
|
|
|
|
if ( capabilities.logarithmicDepthBuffer ) {
|
|
|
|
p_uniforms.setValue( _gl, 'logDepthBufFC',
|
|
2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
|
|
|
|
}
|
|
|
|
|
|
if ( camera !== _currentCamera ) {
|
|
|
|
_currentCamera = camera;
|
|
|
|
// lighting uniforms depend on the camera so enforce an update
|
|
// now, in case this material supports lights - or later, when
|
|
// the next material that does gets activated:
|
|
|
|
refreshMaterial = true; // set to true on material change
|
|
refreshLights = true; // remains set until update done
|
|
|
|
}
|
|
|
|
// load material specific uniforms
|
|
// (shader material also gets them for the sake of genericity)
|
|
|
|
if ( material.isShaderMaterial ||
|
|
material.isMeshPhongMaterial ||
|
|
material.isMeshStandardMaterial ||
|
|
material.envMap ) {
|
|
|
|
var uCamPos = p_uniforms.map.cameraPosition;
|
|
|
|
if ( uCamPos !== undefined ) {
|
|
|
|
uCamPos.setValue( _gl,
|
|
_vector3.setFromMatrixPosition( camera.matrixWorld ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( material.isMeshPhongMaterial ||
|
|
material.isMeshLambertMaterial ||
|
|
material.isMeshBasicMaterial ||
|
|
material.isMeshStandardMaterial ||
|
|
material.isShaderMaterial ||
|
|
material.skinning ) {
|
|
|
|
p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
|
|
|
|
}
|
|
|
|
p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
|
|
p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );
|
|
|
|
}
|
|
|
|
// skinning uniforms must be set even if material didn't change
|
|
// auto-setting of texture unit for bone texture must go before other textures
|
|
// not sure why, but otherwise weird things happen
|
|
|
|
if ( material.skinning ) {
|
|
|
|
p_uniforms.setOptional( _gl, object, 'bindMatrix' );
|
|
p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
|
|
|
|
var skeleton = object.skeleton;
|
|
|
|
if ( skeleton ) {
|
|
|
|
var bones = skeleton.bones;
|
|
|
|
if ( capabilities.floatVertexTextures ) {
|
|
|
|
if ( skeleton.boneTexture === undefined ) {
|
|
|
|
// layout (1 matrix = 4 pixels)
|
|
// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
|
|
// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
|
|
// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
|
|
// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
|
|
// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
|
|
|
|
|
|
var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
|
|
size = _Math.nextPowerOfTwo( Math.ceil( size ) );
|
|
size = Math.max( size, 4 );
|
|
|
|
var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
|
|
boneMatrices.set( skeleton.boneMatrices ); // copy current values
|
|
|
|
var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
|
|
|
|
skeleton.boneMatrices = boneMatrices;
|
|
skeleton.boneTexture = boneTexture;
|
|
skeleton.boneTextureSize = size;
|
|
|
|
}
|
|
|
|
p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
|
|
p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
|
|
|
|
} else {
|
|
|
|
p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( refreshMaterial ) {
|
|
|
|
if ( material.lights ) {
|
|
|
|
// the current material requires lighting info
|
|
|
|
// note: all lighting uniforms are always set correctly
|
|
// they simply reference the renderer's state for their
|
|
// values
|
|
//
|
|
// use the current material's .needsUpdate flags to set
|
|
// the GL state when required
|
|
|
|
markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
|
|
|
|
}
|
|
|
|
// refresh uniforms common to several materials
|
|
|
|
if ( fog && material.fog ) {
|
|
|
|
refreshUniformsFog( m_uniforms, fog );
|
|
|
|
}
|
|
|
|
if ( material.isMeshBasicMaterial ||
|
|
material.isMeshLambertMaterial ||
|
|
material.isMeshPhongMaterial ||
|
|
material.isMeshStandardMaterial ||
|
|
material.isMeshNormalMaterial ||
|
|
material.isMeshDepthMaterial ) {
|
|
|
|
refreshUniformsCommon( m_uniforms, material );
|
|
|
|
}
|
|
|
|
// refresh single material specific uniforms
|
|
|
|
if ( material.isLineBasicMaterial ) {
|
|
|
|
refreshUniformsLine( m_uniforms, material );
|
|
|
|
} else if ( material.isLineDashedMaterial ) {
|
|
|
|
refreshUniformsLine( m_uniforms, material );
|
|
refreshUniformsDash( m_uniforms, material );
|
|
|
|
} else if ( material.isPointsMaterial ) {
|
|
|
|
refreshUniformsPoints( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshLambertMaterial ) {
|
|
|
|
refreshUniformsLambert( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshToonMaterial ) {
|
|
|
|
refreshUniformsToon( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshPhongMaterial ) {
|
|
|
|
refreshUniformsPhong( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshPhysicalMaterial ) {
|
|
|
|
refreshUniformsPhysical( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshStandardMaterial ) {
|
|
|
|
refreshUniformsStandard( m_uniforms, material );
|
|
|
|
} else if ( material.isMeshDepthMaterial ) {
|
|
|
|
if ( material.displacementMap ) {
|
|
|
|
m_uniforms.displacementMap.value = material.displacementMap;
|
|
m_uniforms.displacementScale.value = material.displacementScale;
|
|
m_uniforms.displacementBias.value = material.displacementBias;
|
|
|
|
}
|
|
|
|
} else if ( material.isMeshNormalMaterial ) {
|
|
|
|
refreshUniformsNormal( m_uniforms, material );
|
|
|
|
}
|
|
|
|
// RectAreaLight Texture
|
|
// TODO (mrdoob): Find a nicer implementation
|
|
|
|
if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = UniformsLib.LTC_MAT_TEXTURE;
|
|
if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = UniformsLib.LTC_MAG_TEXTURE;
|
|
|
|
WebGLUniforms.upload(
|
|
_gl, materialProperties.uniformsList, m_uniforms, _this );
|
|
|
|
}
|
|
|
|
|
|
// common matrices
|
|
|
|
p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
|
|
p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
|
|
p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
// Uniforms (refresh uniforms objects)
|
|
|
|
function refreshUniformsCommon( uniforms, material ) {
|
|
|
|
uniforms.opacity.value = material.opacity;
|
|
|
|
uniforms.diffuse.value = material.color;
|
|
|
|
if ( material.emissive ) {
|
|
|
|
uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
|
|
|
|
}
|
|
|
|
uniforms.map.value = material.map;
|
|
uniforms.specularMap.value = material.specularMap;
|
|
uniforms.alphaMap.value = material.alphaMap;
|
|
|
|
if ( material.lightMap ) {
|
|
|
|
uniforms.lightMap.value = material.lightMap;
|
|
uniforms.lightMapIntensity.value = material.lightMapIntensity;
|
|
|
|
}
|
|
|
|
if ( material.aoMap ) {
|
|
|
|
uniforms.aoMap.value = material.aoMap;
|
|
uniforms.aoMapIntensity.value = material.aoMapIntensity;
|
|
|
|
}
|
|
|
|
// uv repeat and offset setting priorities
|
|
// 1. color map
|
|
// 2. specular map
|
|
// 3. normal map
|
|
// 4. bump map
|
|
// 5. alpha map
|
|
// 6. emissive map
|
|
|
|
var uvScaleMap;
|
|
|
|
if ( material.map ) {
|
|
|
|
uvScaleMap = material.map;
|
|
|
|
} else if ( material.specularMap ) {
|
|
|
|
uvScaleMap = material.specularMap;
|
|
|
|
} else if ( material.displacementMap ) {
|
|
|
|
uvScaleMap = material.displacementMap;
|
|
|
|
} else if ( material.normalMap ) {
|
|
|
|
uvScaleMap = material.normalMap;
|
|
|
|
} else if ( material.bumpMap ) {
|
|
|
|
uvScaleMap = material.bumpMap;
|
|
|
|
} else if ( material.roughnessMap ) {
|
|
|
|
uvScaleMap = material.roughnessMap;
|
|
|
|
} else if ( material.metalnessMap ) {
|
|
|
|
uvScaleMap = material.metalnessMap;
|
|
|
|
} else if ( material.alphaMap ) {
|
|
|
|
uvScaleMap = material.alphaMap;
|
|
|
|
} else if ( material.emissiveMap ) {
|
|
|
|
uvScaleMap = material.emissiveMap;
|
|
|
|
}
|
|
|
|
if ( uvScaleMap !== undefined ) {
|
|
|
|
// backwards compatibility
|
|
if ( uvScaleMap.isWebGLRenderTarget ) {
|
|
|
|
uvScaleMap = uvScaleMap.texture;
|
|
|
|
}
|
|
|
|
var offset = uvScaleMap.offset;
|
|
var repeat = uvScaleMap.repeat;
|
|
|
|
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
|
|
|
|
}
|
|
|
|
uniforms.envMap.value = material.envMap;
|
|
|
|
// don't flip CubeTexture envMaps, flip everything else:
|
|
// WebGLRenderTargetCube will be flipped for backwards compatibility
|
|
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
|
|
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
|
|
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
|
|
|
|
uniforms.reflectivity.value = material.reflectivity;
|
|
uniforms.refractionRatio.value = material.refractionRatio;
|
|
|
|
}
|
|
|
|
function refreshUniformsLine( uniforms, material ) {
|
|
|
|
uniforms.diffuse.value = material.color;
|
|
uniforms.opacity.value = material.opacity;
|
|
|
|
}
|
|
|
|
function refreshUniformsDash( uniforms, material ) {
|
|
|
|
uniforms.dashSize.value = material.dashSize;
|
|
uniforms.totalSize.value = material.dashSize + material.gapSize;
|
|
uniforms.scale.value = material.scale;
|
|
|
|
}
|
|
|
|
function refreshUniformsPoints( uniforms, material ) {
|
|
|
|
uniforms.diffuse.value = material.color;
|
|
uniforms.opacity.value = material.opacity;
|
|
uniforms.size.value = material.size * _pixelRatio;
|
|
uniforms.scale.value = _height * 0.5;
|
|
|
|
uniforms.map.value = material.map;
|
|
|
|
if ( material.map !== null ) {
|
|
|
|
var offset = material.map.offset;
|
|
var repeat = material.map.repeat;
|
|
|
|
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsFog( uniforms, fog ) {
|
|
|
|
uniforms.fogColor.value = fog.color;
|
|
|
|
if ( fog.isFog ) {
|
|
|
|
uniforms.fogNear.value = fog.near;
|
|
uniforms.fogFar.value = fog.far;
|
|
|
|
} else if ( fog.isFogExp2 ) {
|
|
|
|
uniforms.fogDensity.value = fog.density;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsLambert( uniforms, material ) {
|
|
|
|
if ( material.emissiveMap ) {
|
|
|
|
uniforms.emissiveMap.value = material.emissiveMap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsPhong( uniforms, material ) {
|
|
|
|
uniforms.specular.value = material.specular;
|
|
uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
|
|
|
|
if ( material.emissiveMap ) {
|
|
|
|
uniforms.emissiveMap.value = material.emissiveMap;
|
|
|
|
}
|
|
|
|
if ( material.bumpMap ) {
|
|
|
|
uniforms.bumpMap.value = material.bumpMap;
|
|
uniforms.bumpScale.value = material.bumpScale;
|
|
|
|
}
|
|
|
|
if ( material.normalMap ) {
|
|
|
|
uniforms.normalMap.value = material.normalMap;
|
|
uniforms.normalScale.value.copy( material.normalScale );
|
|
|
|
}
|
|
|
|
if ( material.displacementMap ) {
|
|
|
|
uniforms.displacementMap.value = material.displacementMap;
|
|
uniforms.displacementScale.value = material.displacementScale;
|
|
uniforms.displacementBias.value = material.displacementBias;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsToon( uniforms, material ) {
|
|
|
|
refreshUniformsPhong( uniforms, material );
|
|
|
|
if ( material.gradientMap ) {
|
|
|
|
uniforms.gradientMap.value = material.gradientMap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsStandard( uniforms, material ) {
|
|
|
|
uniforms.roughness.value = material.roughness;
|
|
uniforms.metalness.value = material.metalness;
|
|
|
|
if ( material.roughnessMap ) {
|
|
|
|
uniforms.roughnessMap.value = material.roughnessMap;
|
|
|
|
}
|
|
|
|
if ( material.metalnessMap ) {
|
|
|
|
uniforms.metalnessMap.value = material.metalnessMap;
|
|
|
|
}
|
|
|
|
if ( material.emissiveMap ) {
|
|
|
|
uniforms.emissiveMap.value = material.emissiveMap;
|
|
|
|
}
|
|
|
|
if ( material.bumpMap ) {
|
|
|
|
uniforms.bumpMap.value = material.bumpMap;
|
|
uniforms.bumpScale.value = material.bumpScale;
|
|
|
|
}
|
|
|
|
if ( material.normalMap ) {
|
|
|
|
uniforms.normalMap.value = material.normalMap;
|
|
uniforms.normalScale.value.copy( material.normalScale );
|
|
|
|
}
|
|
|
|
if ( material.displacementMap ) {
|
|
|
|
uniforms.displacementMap.value = material.displacementMap;
|
|
uniforms.displacementScale.value = material.displacementScale;
|
|
uniforms.displacementBias.value = material.displacementBias;
|
|
|
|
}
|
|
|
|
if ( material.envMap ) {
|
|
|
|
//uniforms.envMap.value = material.envMap; // part of uniforms common
|
|
uniforms.envMapIntensity.value = material.envMapIntensity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshUniformsPhysical( uniforms, material ) {
|
|
|
|
uniforms.clearCoat.value = material.clearCoat;
|
|
uniforms.clearCoatRoughness.value = material.clearCoatRoughness;
|
|
|
|
refreshUniformsStandard( uniforms, material );
|
|
|
|
}
|
|
|
|
function refreshUniformsNormal( uniforms, material ) {
|
|
|
|
if ( material.bumpMap ) {
|
|
|
|
uniforms.bumpMap.value = material.bumpMap;
|
|
uniforms.bumpScale.value = material.bumpScale;
|
|
|
|
}
|
|
|
|
if ( material.normalMap ) {
|
|
|
|
uniforms.normalMap.value = material.normalMap;
|
|
uniforms.normalScale.value.copy( material.normalScale );
|
|
|
|
}
|
|
|
|
if ( material.displacementMap ) {
|
|
|
|
uniforms.displacementMap.value = material.displacementMap;
|
|
uniforms.displacementScale.value = material.displacementScale;
|
|
uniforms.displacementBias.value = material.displacementBias;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If uniforms are marked as clean, they don't need to be loaded to the GPU.
|
|
|
|
function markUniformsLightsNeedsUpdate( uniforms, value ) {
|
|
|
|
uniforms.ambientLightColor.needsUpdate = value;
|
|
|
|
uniforms.directionalLights.needsUpdate = value;
|
|
uniforms.pointLights.needsUpdate = value;
|
|
uniforms.spotLights.needsUpdate = value;
|
|
uniforms.rectAreaLights.needsUpdate = value;
|
|
uniforms.hemisphereLights.needsUpdate = value;
|
|
|
|
}
|
|
|
|
// Lighting
|
|
|
|
function setupShadows( lights ) {
|
|
|
|
var lightShadowsLength = 0;
|
|
|
|
for ( var i = 0, l = lights.length; i < l; i ++ ) {
|
|
|
|
var light = lights[ i ];
|
|
|
|
if ( light.castShadow ) {
|
|
|
|
_lights.shadows[ lightShadowsLength ] = light;
|
|
lightShadowsLength ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_lights.shadows.length = lightShadowsLength;
|
|
|
|
}
|
|
|
|
function setupLights( lights, camera ) {
|
|
|
|
var l, ll, light, shadow,
|
|
r = 0, g = 0, b = 0,
|
|
color,
|
|
intensity,
|
|
distance,
|
|
shadowMap,
|
|
|
|
viewMatrix = camera.matrixWorldInverse,
|
|
|
|
directionalLength = 0,
|
|
pointLength = 0,
|
|
spotLength = 0,
|
|
rectAreaLength = 0,
|
|
hemiLength = 0;
|
|
|
|
for ( l = 0, ll = lights.length; l < ll; l ++ ) {
|
|
|
|
light = lights[ l ];
|
|
|
|
color = light.color;
|
|
intensity = light.intensity;
|
|
distance = light.distance;
|
|
|
|
shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
|
|
|
|
if ( light.isAmbientLight ) {
|
|
|
|
r += color.r * intensity;
|
|
g += color.g * intensity;
|
|
b += color.b * intensity;
|
|
|
|
} else if ( light.isDirectionalLight ) {
|
|
|
|
var uniforms = lightCache.get( light );
|
|
|
|
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
|
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
_vector3.setFromMatrixPosition( light.target.matrixWorld );
|
|
uniforms.direction.sub( _vector3 );
|
|
uniforms.direction.transformDirection( viewMatrix );
|
|
|
|
uniforms.shadow = light.castShadow;
|
|
|
|
if ( light.castShadow ) {
|
|
|
|
shadow = light.shadow;
|
|
|
|
uniforms.shadowBias = shadow.bias;
|
|
uniforms.shadowRadius = shadow.radius;
|
|
uniforms.shadowMapSize = shadow.mapSize;
|
|
|
|
}
|
|
|
|
_lights.directionalShadowMap[ directionalLength ] = shadowMap;
|
|
_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
|
|
_lights.directional[ directionalLength ] = uniforms;
|
|
|
|
directionalLength ++;
|
|
|
|
} else if ( light.isSpotLight ) {
|
|
|
|
var uniforms = lightCache.get( light );
|
|
|
|
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
|
uniforms.position.applyMatrix4( viewMatrix );
|
|
|
|
uniforms.color.copy( color ).multiplyScalar( intensity );
|
|
uniforms.distance = distance;
|
|
|
|
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
_vector3.setFromMatrixPosition( light.target.matrixWorld );
|
|
uniforms.direction.sub( _vector3 );
|
|
uniforms.direction.transformDirection( viewMatrix );
|
|
|
|
uniforms.coneCos = Math.cos( light.angle );
|
|
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
|
|
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
|
uniforms.shadow = light.castShadow;
|
|
|
|
if ( light.castShadow ) {
|
|
|
|
shadow = light.shadow;
|
|
|
|
uniforms.shadowBias = shadow.bias;
|
|
uniforms.shadowRadius = shadow.radius;
|
|
uniforms.shadowMapSize = shadow.mapSize;
|
|
|
|
}
|
|
|
|
_lights.spotShadowMap[ spotLength ] = shadowMap;
|
|
_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
|
|
_lights.spot[ spotLength ] = uniforms;
|
|
|
|
spotLength ++;
|
|
|
|
} else if ( light.isRectAreaLight ) {
|
|
|
|
var uniforms = lightCache.get( light );
|
|
|
|
// (a) intensity controls irradiance of entire light
|
|
uniforms.color
|
|
.copy( color )
|
|
.multiplyScalar( intensity / ( light.width * light.height ) );
|
|
|
|
// (b) intensity controls the radiance per light area
|
|
// uniforms.color.copy( color ).multiplyScalar( intensity );
|
|
|
|
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
|
uniforms.position.applyMatrix4( viewMatrix );
|
|
|
|
// extract local rotation of light to derive width/height half vectors
|
|
_matrix42.identity();
|
|
_matrix4.copy( light.matrixWorld );
|
|
_matrix4.premultiply( viewMatrix );
|
|
_matrix42.extractRotation( _matrix4 );
|
|
|
|
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
|
|
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
|
|
|
|
uniforms.halfWidth.applyMatrix4( _matrix42 );
|
|
uniforms.halfHeight.applyMatrix4( _matrix42 );
|
|
|
|
// TODO (abelnation): RectAreaLight distance?
|
|
// uniforms.distance = distance;
|
|
|
|
_lights.rectArea[ rectAreaLength ] = uniforms;
|
|
|
|
rectAreaLength ++;
|
|
|
|
} else if ( light.isPointLight ) {
|
|
|
|
var uniforms = lightCache.get( light );
|
|
|
|
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
|
uniforms.position.applyMatrix4( viewMatrix );
|
|
|
|
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
|
uniforms.distance = light.distance;
|
|
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
|
uniforms.shadow = light.castShadow;
|
|
|
|
if ( light.castShadow ) {
|
|
|
|
shadow = light.shadow;
|
|
|
|
uniforms.shadowBias = shadow.bias;
|
|
uniforms.shadowRadius = shadow.radius;
|
|
uniforms.shadowMapSize = shadow.mapSize;
|
|
|
|
}
|
|
|
|
_lights.pointShadowMap[ pointLength ] = shadowMap;
|
|
_lights.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
|
|
_lights.point[ pointLength ] = uniforms;
|
|
|
|
pointLength ++;
|
|
|
|
} else if ( light.isHemisphereLight ) {
|
|
|
|
var uniforms = lightCache.get( light );
|
|
|
|
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
uniforms.direction.transformDirection( viewMatrix );
|
|
uniforms.direction.normalize();
|
|
|
|
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
|
|
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
|
|
|
|
_lights.hemi[ hemiLength ] = uniforms;
|
|
|
|
hemiLength ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_lights.ambient[ 0 ] = r;
|
|
_lights.ambient[ 1 ] = g;
|
|
_lights.ambient[ 2 ] = b;
|
|
|
|
_lights.directional.length = directionalLength;
|
|
_lights.spot.length = spotLength;
|
|
_lights.rectArea.length = rectAreaLength;
|
|
_lights.point.length = pointLength;
|
|
_lights.hemi.length = hemiLength;
|
|
|
|
// TODO (sam-g-steel) why aren't we using join
|
|
_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;
|
|
|
|
}
|
|
|
|
// GL state setting
|
|
|
|
this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
|
|
|
|
state.setCullFace( cullFace );
|
|
state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
|
|
|
|
};
|
|
|
|
// Textures
|
|
|
|
function allocTextureUnit() {
|
|
|
|
var textureUnit = _usedTextureUnits;
|
|
|
|
if ( textureUnit >= capabilities.maxTextures ) {
|
|
|
|
console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
|
|
|
|
}
|
|
|
|
_usedTextureUnits += 1;
|
|
|
|
return textureUnit;
|
|
|
|
}
|
|
|
|
this.allocTextureUnit = allocTextureUnit;
|
|
|
|
// this.setTexture2D = setTexture2D;
|
|
this.setTexture2D = ( function () {
|
|
|
|
var warned = false;
|
|
|
|
// backwards compatibility: peel texture.texture
|
|
return function setTexture2D( texture, slot ) {
|
|
|
|
if ( texture && texture.isWebGLRenderTarget ) {
|
|
|
|
if ( ! warned ) {
|
|
|
|
console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." );
|
|
warned = true;
|
|
|
|
}
|
|
|
|
texture = texture.texture;
|
|
|
|
}
|
|
|
|
textures.setTexture2D( texture, slot );
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
this.setTexture = ( function () {
|
|
|
|
var warned = false;
|
|
|
|
return function setTexture( texture, slot ) {
|
|
|
|
if ( ! warned ) {
|
|
|
|
console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." );
|
|
warned = true;
|
|
|
|
}
|
|
|
|
textures.setTexture2D( texture, slot );
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
this.setTextureCube = ( function () {
|
|
|
|
var warned = false;
|
|
|
|
return function setTextureCube( texture, slot ) {
|
|
|
|
// backwards compatibility: peel texture.texture
|
|
if ( texture && texture.isWebGLRenderTargetCube ) {
|
|
|
|
if ( ! warned ) {
|
|
|
|
console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
|
|
warned = true;
|
|
|
|
}
|
|
|
|
texture = texture.texture;
|
|
|
|
}
|
|
|
|
// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
|
|
// TODO: unify these code paths
|
|
if ( ( texture && texture.isCubeTexture ) ||
|
|
( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
|
|
|
|
// CompressedTexture can have Array in image :/
|
|
|
|
// this function alone should take care of cube textures
|
|
textures.setTextureCube( texture, slot );
|
|
|
|
} else {
|
|
|
|
// assumed: texture property of THREE.WebGLRenderTargetCube
|
|
|
|
textures.setTextureCubeDynamic( texture, slot );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
this.getRenderTarget = function () {
|
|
|
|
return _currentRenderTarget;
|
|
|
|
};
|
|
|
|
this.setRenderTarget = function ( renderTarget ) {
|
|
|
|
_currentRenderTarget = renderTarget;
|
|
|
|
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
|
|
|
|
textures.setupRenderTarget( renderTarget );
|
|
|
|
}
|
|
|
|
var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
|
|
var framebuffer;
|
|
|
|
if ( renderTarget ) {
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
if ( isCube ) {
|
|
|
|
framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
|
|
|
|
} else {
|
|
|
|
framebuffer = renderTargetProperties.__webglFramebuffer;
|
|
|
|
}
|
|
|
|
_currentScissor.copy( renderTarget.scissor );
|
|
_currentScissorTest = renderTarget.scissorTest;
|
|
|
|
_currentViewport.copy( renderTarget.viewport );
|
|
|
|
} else {
|
|
|
|
framebuffer = null;
|
|
|
|
_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
|
|
_currentScissorTest = _scissorTest;
|
|
|
|
_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
|
|
|
|
}
|
|
|
|
if ( _currentFramebuffer !== framebuffer ) {
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
_currentFramebuffer = framebuffer;
|
|
|
|
}
|
|
|
|
state.scissor( _currentScissor );
|
|
state.setScissorTest( _currentScissorTest );
|
|
|
|
state.viewport( _currentViewport );
|
|
|
|
if ( isCube ) {
|
|
|
|
var textureProperties = properties.get( renderTarget.texture );
|
|
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
|
|
|
|
if ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
|
|
return;
|
|
|
|
}
|
|
|
|
var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
|
|
|
|
if ( framebuffer ) {
|
|
|
|
var restore = false;
|
|
|
|
if ( framebuffer !== _currentFramebuffer ) {
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
|
|
restore = true;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
var texture = renderTarget.texture;
|
|
var textureFormat = texture.format;
|
|
var textureType = texture.type;
|
|
|
|
if ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
|
|
! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
|
|
! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
|
|
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
|
|
|
|
// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
|
|
|
|
if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
|
|
|
|
_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
if ( restore ) {
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Map three.js constants to WebGL constants
|
|
|
|
function paramThreeToGL( p ) {
|
|
|
|
var extension;
|
|
|
|
if ( p === RepeatWrapping ) return _gl.REPEAT;
|
|
if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
|
|
if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
|
|
|
|
if ( p === NearestFilter ) return _gl.NEAREST;
|
|
if ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
|
|
if ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
|
|
|
|
if ( p === LinearFilter ) return _gl.LINEAR;
|
|
if ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
|
|
if ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
|
|
|
|
if ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;
|
|
if ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
|
|
if ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
|
|
if ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
|
|
|
|
if ( p === ByteType ) return _gl.BYTE;
|
|
if ( p === ShortType ) return _gl.SHORT;
|
|
if ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;
|
|
if ( p === IntType ) return _gl.INT;
|
|
if ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;
|
|
if ( p === FloatType ) return _gl.FLOAT;
|
|
|
|
if ( p === HalfFloatType ) {
|
|
|
|
extension = extensions.get( 'OES_texture_half_float' );
|
|
|
|
if ( extension !== null ) return extension.HALF_FLOAT_OES;
|
|
|
|
}
|
|
|
|
if ( p === AlphaFormat ) return _gl.ALPHA;
|
|
if ( p === RGBFormat ) return _gl.RGB;
|
|
if ( p === RGBAFormat ) return _gl.RGBA;
|
|
if ( p === LuminanceFormat ) return _gl.LUMINANCE;
|
|
if ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
|
|
if ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;
|
|
if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
|
|
|
|
if ( p === AddEquation ) return _gl.FUNC_ADD;
|
|
if ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;
|
|
if ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
|
|
|
|
if ( p === ZeroFactor ) return _gl.ZERO;
|
|
if ( p === OneFactor ) return _gl.ONE;
|
|
if ( p === SrcColorFactor ) return _gl.SRC_COLOR;
|
|
if ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
|
|
if ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;
|
|
if ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
|
|
if ( p === DstAlphaFactor ) return _gl.DST_ALPHA;
|
|
if ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
|
|
|
|
if ( p === DstColorFactor ) return _gl.DST_COLOR;
|
|
if ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
|
|
if ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
|
|
|
|
if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
|
|
p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
|
|
|
|
extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
|
|
|
|
if ( extension !== null ) {
|
|
|
|
if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
|
|
if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
|
if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
|
|
p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
|
|
|
|
extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
|
|
|
|
if ( extension !== null ) {
|
|
|
|
if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
|
if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
|
if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
|
if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( p === RGB_ETC1_Format ) {
|
|
|
|
extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
|
|
|
|
if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
|
|
|
|
}
|
|
|
|
if ( p === MinEquation || p === MaxEquation ) {
|
|
|
|
extension = extensions.get( 'EXT_blend_minmax' );
|
|
|
|
if ( extension !== null ) {
|
|
|
|
if ( p === MinEquation ) return extension.MIN_EXT;
|
|
if ( p === MaxEquation ) return extension.MAX_EXT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( p === UnsignedInt248Type ) {
|
|
|
|
extension = extensions.get( 'WEBGL_depth_texture' );
|
|
|
|
if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function FogExp2 ( color, density ) {
|
|
|
|
this.name = '';
|
|
|
|
this.color = new Color( color );
|
|
this.density = ( density !== undefined ) ? density : 0.00025;
|
|
|
|
}
|
|
|
|
FogExp2.prototype.isFogExp2 = true;
|
|
|
|
FogExp2.prototype.clone = function () {
|
|
|
|
return new FogExp2( this.color.getHex(), this.density );
|
|
|
|
};
|
|
|
|
FogExp2.prototype.toJSON = function ( meta ) {
|
|
|
|
return {
|
|
type: 'FogExp2',
|
|
color: this.color.getHex(),
|
|
density: this.density
|
|
};
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Fog ( color, near, far ) {
|
|
|
|
this.name = '';
|
|
|
|
this.color = new Color( color );
|
|
|
|
this.near = ( near !== undefined ) ? near : 1;
|
|
this.far = ( far !== undefined ) ? far : 1000;
|
|
|
|
}
|
|
|
|
Fog.prototype.isFog = true;
|
|
|
|
Fog.prototype.clone = function () {
|
|
|
|
return new Fog( this.color.getHex(), this.near, this.far );
|
|
|
|
};
|
|
|
|
Fog.prototype.toJSON = function ( meta ) {
|
|
|
|
return {
|
|
type: 'Fog',
|
|
color: this.color.getHex(),
|
|
near: this.near,
|
|
far: this.far
|
|
};
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Scene () {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Scene';
|
|
|
|
this.background = null;
|
|
this.fog = null;
|
|
this.overrideMaterial = null;
|
|
|
|
this.autoUpdate = true; // checked by the renderer
|
|
|
|
}
|
|
|
|
Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Scene,
|
|
|
|
copy: function ( source, recursive ) {
|
|
|
|
Object3D.prototype.copy.call( this, source, recursive );
|
|
|
|
if ( source.background !== null ) this.background = source.background.clone();
|
|
if ( source.fog !== null ) this.fog = source.fog.clone();
|
|
if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
|
|
|
|
this.autoUpdate = source.autoUpdate;
|
|
this.matrixAutoUpdate = source.matrixAutoUpdate;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Object3D.prototype.toJSON.call( this, meta );
|
|
|
|
if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
|
|
if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function LensFlare( texture, size, distance, blending, color ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.lensFlares = [];
|
|
|
|
this.positionScreen = new Vector3();
|
|
this.customUpdateCallback = undefined;
|
|
|
|
if ( texture !== undefined ) {
|
|
|
|
this.add( texture, size, distance, blending, color );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: LensFlare,
|
|
|
|
isLensFlare: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Object3D.prototype.copy.call( this, source );
|
|
|
|
this.positionScreen.copy( source.positionScreen );
|
|
this.customUpdateCallback = source.customUpdateCallback;
|
|
|
|
for ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {
|
|
|
|
this.lensFlares.push( source.lensFlares[ i ] );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
add: function ( texture, size, distance, blending, color, opacity ) {
|
|
|
|
if ( size === undefined ) size = - 1;
|
|
if ( distance === undefined ) distance = 0;
|
|
if ( opacity === undefined ) opacity = 1;
|
|
if ( color === undefined ) color = new Color( 0xffffff );
|
|
if ( blending === undefined ) blending = NormalBlending;
|
|
|
|
distance = Math.min( distance, Math.max( 0, distance ) );
|
|
|
|
this.lensFlares.push( {
|
|
texture: texture, // THREE.Texture
|
|
size: size, // size in pixels (-1 = use texture.width)
|
|
distance: distance, // distance (0-1) from light source (0=at light source)
|
|
x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is in front z = 1 is back
|
|
scale: 1, // scale
|
|
rotation: 0, // rotation
|
|
opacity: opacity, // opacity
|
|
color: color, // color
|
|
blending: blending // blending
|
|
} );
|
|
|
|
},
|
|
|
|
/*
|
|
* Update lens flares update positions on all flares based on the screen position
|
|
* Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
|
|
*/
|
|
|
|
updateLensFlares: function () {
|
|
|
|
var f, fl = this.lensFlares.length;
|
|
var flare;
|
|
var vecX = - this.positionScreen.x * 2;
|
|
var vecY = - this.positionScreen.y * 2;
|
|
|
|
for ( f = 0; f < fl; f ++ ) {
|
|
|
|
flare = this.lensFlares[ f ];
|
|
|
|
flare.x = this.positionScreen.x + vecX * flare.distance;
|
|
flare.y = this.positionScreen.y + vecY * flare.distance;
|
|
|
|
flare.wantedRotation = flare.x * Math.PI * 0.25;
|
|
flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* uvOffset: new THREE.Vector2(),
|
|
* uvScale: new THREE.Vector2()
|
|
* }
|
|
*/
|
|
|
|
function SpriteMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'SpriteMaterial';
|
|
|
|
this.color = new Color( 0xffffff );
|
|
this.map = null;
|
|
|
|
this.rotation = 0;
|
|
|
|
this.fog = false;
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
SpriteMaterial.prototype = Object.create( Material.prototype );
|
|
SpriteMaterial.prototype.constructor = SpriteMaterial;
|
|
SpriteMaterial.prototype.isSpriteMaterial = true;
|
|
|
|
SpriteMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
this.map = source.map;
|
|
|
|
this.rotation = source.rotation;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Sprite( material ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Sprite';
|
|
|
|
this.material = ( material !== undefined ) ? material : new SpriteMaterial();
|
|
|
|
}
|
|
|
|
Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Sprite,
|
|
|
|
isSprite: true,
|
|
|
|
raycast: ( function () {
|
|
|
|
var intersectPoint = new Vector3();
|
|
var worldPosition = new Vector3();
|
|
var worldScale = new Vector3();
|
|
|
|
return function raycast( raycaster, intersects ) {
|
|
|
|
worldPosition.setFromMatrixPosition( this.matrixWorld );
|
|
raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
|
|
|
|
worldScale.setFromMatrixScale( this.matrixWorld );
|
|
var guessSizeSq = worldScale.x * worldScale.y / 4;
|
|
|
|
if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( intersectPoint );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) return;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
point: intersectPoint.clone(),
|
|
face: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
}() ),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.material ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function LOD() {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'LOD';
|
|
|
|
Object.defineProperties( this, {
|
|
levels: {
|
|
enumerable: true,
|
|
value: []
|
|
}
|
|
} );
|
|
|
|
}
|
|
|
|
LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: LOD,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Object3D.prototype.copy.call( this, source, false );
|
|
|
|
var levels = source.levels;
|
|
|
|
for ( var i = 0, l = levels.length; i < l; i ++ ) {
|
|
|
|
var level = levels[ i ];
|
|
|
|
this.addLevel( level.object.clone(), level.distance );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
addLevel: function ( object, distance ) {
|
|
|
|
if ( distance === undefined ) distance = 0;
|
|
|
|
distance = Math.abs( distance );
|
|
|
|
var levels = this.levels;
|
|
|
|
for ( var l = 0; l < levels.length; l ++ ) {
|
|
|
|
if ( distance < levels[ l ].distance ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
levels.splice( l, 0, { distance: distance, object: object } );
|
|
|
|
this.add( object );
|
|
|
|
},
|
|
|
|
getObjectForDistance: function ( distance ) {
|
|
|
|
var levels = this.levels;
|
|
|
|
for ( var i = 1, l = levels.length; i < l; i ++ ) {
|
|
|
|
if ( distance < levels[ i ].distance ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return levels[ i - 1 ].object;
|
|
|
|
},
|
|
|
|
raycast: ( function () {
|
|
|
|
var matrixPosition = new Vector3();
|
|
|
|
return function raycast( raycaster, intersects ) {
|
|
|
|
matrixPosition.setFromMatrixPosition( this.matrixWorld );
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( matrixPosition );
|
|
|
|
this.getObjectForDistance( distance ).raycast( raycaster, intersects );
|
|
|
|
};
|
|
|
|
}() ),
|
|
|
|
update: function () {
|
|
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
|
|
return function update( camera ) {
|
|
|
|
var levels = this.levels;
|
|
|
|
if ( levels.length > 1 ) {
|
|
|
|
v1.setFromMatrixPosition( camera.matrixWorld );
|
|
v2.setFromMatrixPosition( this.matrixWorld );
|
|
|
|
var distance = v1.distanceTo( v2 );
|
|
|
|
levels[ 0 ].object.visible = true;
|
|
|
|
for ( var i = 1, l = levels.length; i < l; i ++ ) {
|
|
|
|
if ( distance >= levels[ i ].distance ) {
|
|
|
|
levels[ i - 1 ].object.visible = false;
|
|
levels[ i ].object.visible = true;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( ; i < l; i ++ ) {
|
|
|
|
levels[ i ].object.visible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Object3D.prototype.toJSON.call( this, meta );
|
|
|
|
data.object.levels = [];
|
|
|
|
var levels = this.levels;
|
|
|
|
for ( var i = 0, l = levels.length; i < l; i ++ ) {
|
|
|
|
var level = levels[ i ];
|
|
|
|
data.object.levels.push( {
|
|
object: level.object.uuid,
|
|
distance: level.distance
|
|
} );
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author michael guerrero / http://realitymeltdown.com
|
|
* @author ikerr / http://verold.com
|
|
*/
|
|
|
|
function Skeleton( bones, boneInverses ) {
|
|
|
|
// copy the bone array
|
|
|
|
bones = bones || [];
|
|
|
|
this.bones = bones.slice( 0 );
|
|
this.boneMatrices = new Float32Array( this.bones.length * 16 );
|
|
|
|
// use the supplied bone inverses or calculate the inverses
|
|
|
|
if ( boneInverses === undefined ) {
|
|
|
|
this.calculateInverses();
|
|
|
|
} else {
|
|
|
|
if ( this.bones.length === boneInverses.length ) {
|
|
|
|
this.boneInverses = boneInverses.slice( 0 );
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.Skeleton boneInverses is the wrong length.' );
|
|
|
|
this.boneInverses = [];
|
|
|
|
for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
|
|
|
|
this.boneInverses.push( new Matrix4() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Object.assign( Skeleton.prototype, {
|
|
|
|
calculateInverses: function () {
|
|
|
|
this.boneInverses = [];
|
|
|
|
for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
|
|
|
|
var inverse = new Matrix4();
|
|
|
|
if ( this.bones[ i ] ) {
|
|
|
|
inverse.getInverse( this.bones[ i ].matrixWorld );
|
|
|
|
}
|
|
|
|
this.boneInverses.push( inverse );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pose: function () {
|
|
|
|
var bone, i, il;
|
|
|
|
// recover the bind-time world matrices
|
|
|
|
for ( i = 0, il = this.bones.length; i < il; i ++ ) {
|
|
|
|
bone = this.bones[ i ];
|
|
|
|
if ( bone ) {
|
|
|
|
bone.matrixWorld.getInverse( this.boneInverses[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// compute the local matrices, positions, rotations and scales
|
|
|
|
for ( i = 0, il = this.bones.length; i < il; i ++ ) {
|
|
|
|
bone = this.bones[ i ];
|
|
|
|
if ( bone ) {
|
|
|
|
if ( bone.parent && bone.parent.isBone ) {
|
|
|
|
bone.matrix.getInverse( bone.parent.matrixWorld );
|
|
bone.matrix.multiply( bone.matrixWorld );
|
|
|
|
} else {
|
|
|
|
bone.matrix.copy( bone.matrixWorld );
|
|
|
|
}
|
|
|
|
bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
update: ( function () {
|
|
|
|
var offsetMatrix = new Matrix4();
|
|
var identityMatrix = new Matrix4();
|
|
|
|
return function update() {
|
|
|
|
var bones = this.bones;
|
|
var boneInverses = this.boneInverses;
|
|
var boneMatrices = this.boneMatrices;
|
|
var boneTexture = this.boneTexture;
|
|
|
|
// flatten bone matrices to array
|
|
|
|
for ( var i = 0, il = bones.length; i < il; i ++ ) {
|
|
|
|
// compute the offset between the current and the original transform
|
|
|
|
var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix;
|
|
|
|
offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
|
|
offsetMatrix.toArray( boneMatrices, i * 16 );
|
|
|
|
}
|
|
|
|
if ( boneTexture !== undefined ) {
|
|
|
|
boneTexture.needsUpdate = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} )(),
|
|
|
|
clone: function () {
|
|
|
|
return new Skeleton( this.bones, this.boneInverses );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author ikerr / http://verold.com
|
|
*/
|
|
|
|
function Bone() {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Bone';
|
|
|
|
}
|
|
|
|
Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Bone,
|
|
|
|
isBone: true
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mikael emtinger / http://gomo.se/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author ikerr / http://verold.com
|
|
*/
|
|
|
|
function SkinnedMesh( geometry, material ) {
|
|
|
|
Mesh.call( this, geometry, material );
|
|
|
|
this.type = 'SkinnedMesh';
|
|
|
|
this.bindMode = 'attached';
|
|
this.bindMatrix = new Matrix4();
|
|
this.bindMatrixInverse = new Matrix4();
|
|
|
|
var bones = this.initBones();
|
|
var skeleton = new Skeleton( bones );
|
|
|
|
this.bind( skeleton, this.matrixWorld );
|
|
|
|
this.normalizeSkinWeights();
|
|
|
|
}
|
|
|
|
SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
|
|
|
|
constructor: SkinnedMesh,
|
|
|
|
isSkinnedMesh: true,
|
|
|
|
initBones: function () {
|
|
|
|
var bones = [], bone, gbone;
|
|
var i, il;
|
|
|
|
if ( this.geometry && this.geometry.bones !== undefined ) {
|
|
|
|
// first, create array of 'Bone' objects from geometry data
|
|
|
|
for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
|
|
|
|
gbone = this.geometry.bones[ i ];
|
|
|
|
// create new 'Bone' object
|
|
|
|
bone = new Bone();
|
|
bones.push( bone );
|
|
|
|
// apply values
|
|
|
|
bone.name = gbone.name;
|
|
bone.position.fromArray( gbone.pos );
|
|
bone.quaternion.fromArray( gbone.rotq );
|
|
if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
|
|
|
|
}
|
|
|
|
// second, create bone hierarchy
|
|
|
|
for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
|
|
|
|
gbone = this.geometry.bones[ i ];
|
|
|
|
if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) {
|
|
|
|
// subsequent bones in the hierarchy
|
|
|
|
bones[ gbone.parent ].add( bones[ i ] );
|
|
|
|
} else {
|
|
|
|
// topmost bone, immediate child of the skinned mesh
|
|
|
|
this.add( bones[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now the bones are part of the scene graph and children of the skinned mesh.
|
|
// let's update the corresponding matrices
|
|
|
|
this.updateMatrixWorld( true );
|
|
|
|
return bones;
|
|
|
|
},
|
|
|
|
bind: function ( skeleton, bindMatrix ) {
|
|
|
|
this.skeleton = skeleton;
|
|
|
|
if ( bindMatrix === undefined ) {
|
|
|
|
this.updateMatrixWorld( true );
|
|
|
|
this.skeleton.calculateInverses();
|
|
|
|
bindMatrix = this.matrixWorld;
|
|
|
|
}
|
|
|
|
this.bindMatrix.copy( bindMatrix );
|
|
this.bindMatrixInverse.getInverse( bindMatrix );
|
|
|
|
},
|
|
|
|
pose: function () {
|
|
|
|
this.skeleton.pose();
|
|
|
|
},
|
|
|
|
normalizeSkinWeights: function () {
|
|
|
|
var scale, i;
|
|
|
|
if ( this.geometry && this.geometry.isGeometry ) {
|
|
|
|
for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) {
|
|
|
|
var sw = this.geometry.skinWeights[ i ];
|
|
|
|
scale = 1.0 / sw.lengthManhattan();
|
|
|
|
if ( scale !== Infinity ) {
|
|
|
|
sw.multiplyScalar( scale );
|
|
|
|
} else {
|
|
|
|
sw.set( 1, 0, 0, 0 ); // do something reasonable
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( this.geometry && this.geometry.isBufferGeometry ) {
|
|
|
|
var vec = new Vector4();
|
|
|
|
var skinWeight = this.geometry.attributes.skinWeight;
|
|
|
|
for ( i = 0; i < skinWeight.count; i ++ ) {
|
|
|
|
vec.x = skinWeight.getX( i );
|
|
vec.y = skinWeight.getY( i );
|
|
vec.z = skinWeight.getZ( i );
|
|
vec.w = skinWeight.getW( i );
|
|
|
|
scale = 1.0 / vec.lengthManhattan();
|
|
|
|
if ( scale !== Infinity ) {
|
|
|
|
vec.multiplyScalar( scale );
|
|
|
|
} else {
|
|
|
|
vec.set( 1, 0, 0, 0 ); // do something reasonable
|
|
|
|
}
|
|
|
|
skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
updateMatrixWorld: function ( force ) {
|
|
|
|
Mesh.prototype.updateMatrixWorld.call( this, force );
|
|
|
|
if ( this.bindMode === 'attached' ) {
|
|
|
|
this.bindMatrixInverse.getInverse( this.matrixWorld );
|
|
|
|
} else if ( this.bindMode === 'detached' ) {
|
|
|
|
this.bindMatrixInverse.getInverse( this.bindMatrix );
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.geometry, this.material ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
*
|
|
* linewidth: <float>,
|
|
* linecap: "round",
|
|
* linejoin: "round"
|
|
* }
|
|
*/
|
|
|
|
function LineBasicMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'LineBasicMaterial';
|
|
|
|
this.color = new Color( 0xffffff );
|
|
|
|
this.linewidth = 1;
|
|
this.linecap = 'round';
|
|
this.linejoin = 'round';
|
|
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
LineBasicMaterial.prototype = Object.create( Material.prototype );
|
|
LineBasicMaterial.prototype.constructor = LineBasicMaterial;
|
|
|
|
LineBasicMaterial.prototype.isLineBasicMaterial = true;
|
|
|
|
LineBasicMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
|
|
this.linewidth = source.linewidth;
|
|
this.linecap = source.linecap;
|
|
this.linejoin = source.linejoin;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Line( geometry, material, mode ) {
|
|
|
|
if ( mode === 1 ) {
|
|
|
|
console.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );
|
|
return new LineSegments( geometry, material );
|
|
|
|
}
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Line';
|
|
|
|
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
|
|
this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );
|
|
|
|
}
|
|
|
|
Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Line,
|
|
|
|
isLine: true,
|
|
|
|
raycast: ( function () {
|
|
|
|
var inverseMatrix = new Matrix4();
|
|
var ray = new Ray();
|
|
var sphere = new Sphere();
|
|
|
|
return function raycast( raycaster, intersects ) {
|
|
|
|
var precision = raycaster.linePrecision;
|
|
var precisionSq = precision * precision;
|
|
|
|
var geometry = this.geometry;
|
|
var matrixWorld = this.matrixWorld;
|
|
|
|
// Checking boundingSphere distance to ray
|
|
|
|
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
|
|
|
sphere.copy( geometry.boundingSphere );
|
|
sphere.applyMatrix4( matrixWorld );
|
|
|
|
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
|
|
|
|
//
|
|
|
|
inverseMatrix.getInverse( matrixWorld );
|
|
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
|
|
|
|
var vStart = new Vector3();
|
|
var vEnd = new Vector3();
|
|
var interSegment = new Vector3();
|
|
var interRay = new Vector3();
|
|
var step = (this && this.isLineSegments) ? 2 : 1;
|
|
|
|
if ( geometry.isBufferGeometry ) {
|
|
|
|
var index = geometry.index;
|
|
var attributes = geometry.attributes;
|
|
var positions = attributes.position.array;
|
|
|
|
if ( index !== null ) {
|
|
|
|
var indices = index.array;
|
|
|
|
for ( var i = 0, l = indices.length - 1; i < l; i += step ) {
|
|
|
|
var a = indices[ i ];
|
|
var b = indices[ i + 1 ];
|
|
|
|
vStart.fromArray( positions, a * 3 );
|
|
vEnd.fromArray( positions, b * 3 );
|
|
|
|
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {
|
|
|
|
vStart.fromArray( positions, 3 * i );
|
|
vEnd.fromArray( positions, 3 * i + 3 );
|
|
|
|
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( geometry.isGeometry ) {
|
|
|
|
var vertices = geometry.vertices;
|
|
var nbVertices = vertices.length;
|
|
|
|
for ( var i = 0; i < nbVertices - 1; i += step ) {
|
|
|
|
var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() ),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.geometry, this.material ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function LineSegments( geometry, material ) {
|
|
|
|
Line.call( this, geometry, material );
|
|
|
|
this.type = 'LineSegments';
|
|
|
|
}
|
|
|
|
LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
|
|
|
|
constructor: LineSegments,
|
|
|
|
isLineSegments: true
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mgreter / http://github.com/mgreter
|
|
*/
|
|
|
|
function LineLoop( geometry, material ) {
|
|
|
|
Line.call( this, geometry, material );
|
|
|
|
this.type = 'LineLoop';
|
|
|
|
}
|
|
|
|
LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
|
|
|
|
constructor: LineLoop,
|
|
|
|
isLineLoop: true,
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* size: <float>,
|
|
* sizeAttenuation: <bool>
|
|
* }
|
|
*/
|
|
|
|
function PointsMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'PointsMaterial';
|
|
|
|
this.color = new Color( 0xffffff );
|
|
|
|
this.map = null;
|
|
|
|
this.size = 1;
|
|
this.sizeAttenuation = true;
|
|
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
PointsMaterial.prototype = Object.create( Material.prototype );
|
|
PointsMaterial.prototype.constructor = PointsMaterial;
|
|
|
|
PointsMaterial.prototype.isPointsMaterial = true;
|
|
|
|
PointsMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
|
|
this.map = source.map;
|
|
|
|
this.size = source.size;
|
|
this.sizeAttenuation = source.sizeAttenuation;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Points( geometry, material ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Points';
|
|
|
|
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
|
|
this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );
|
|
|
|
}
|
|
|
|
Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Points,
|
|
|
|
isPoints: true,
|
|
|
|
raycast: ( function () {
|
|
|
|
var inverseMatrix = new Matrix4();
|
|
var ray = new Ray();
|
|
var sphere = new Sphere();
|
|
|
|
return function raycast( raycaster, intersects ) {
|
|
|
|
var object = this;
|
|
var geometry = this.geometry;
|
|
var matrixWorld = this.matrixWorld;
|
|
var threshold = raycaster.params.Points.threshold;
|
|
|
|
// Checking boundingSphere distance to ray
|
|
|
|
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
|
|
|
sphere.copy( geometry.boundingSphere );
|
|
sphere.applyMatrix4( matrixWorld );
|
|
sphere.radius += threshold;
|
|
|
|
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
|
|
|
|
//
|
|
|
|
inverseMatrix.getInverse( matrixWorld );
|
|
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
|
|
|
|
var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
|
|
var localThresholdSq = localThreshold * localThreshold;
|
|
var position = new Vector3();
|
|
|
|
function testPoint( point, index ) {
|
|
|
|
var rayPointDistanceSq = ray.distanceSqToPoint( point );
|
|
|
|
if ( rayPointDistanceSq < localThresholdSq ) {
|
|
|
|
var intersectPoint = ray.closestPointToPoint( point );
|
|
intersectPoint.applyMatrix4( matrixWorld );
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( intersectPoint );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) return;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
distanceToRay: Math.sqrt( rayPointDistanceSq ),
|
|
point: intersectPoint.clone(),
|
|
index: index,
|
|
face: null,
|
|
object: object
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( geometry.isBufferGeometry ) {
|
|
|
|
var index = geometry.index;
|
|
var attributes = geometry.attributes;
|
|
var positions = attributes.position.array;
|
|
|
|
if ( index !== null ) {
|
|
|
|
var indices = index.array;
|
|
|
|
for ( var i = 0, il = indices.length; i < il; i ++ ) {
|
|
|
|
var a = indices[ i ];
|
|
|
|
position.fromArray( positions, a * 3 );
|
|
|
|
testPoint( position, a );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( var i = 0, l = positions.length / 3; i < l; i ++ ) {
|
|
|
|
position.fromArray( positions, i * 3 );
|
|
|
|
testPoint( position, i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var vertices = geometry.vertices;
|
|
|
|
for ( var i = 0, l = vertices.length; i < l; i ++ ) {
|
|
|
|
testPoint( vertices[ i ], i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() ),
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor( this.geometry, this.material ).copy( this );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Group() {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Group';
|
|
|
|
}
|
|
|
|
Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Group
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
|
|
|
|
Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
|
|
|
|
this.generateMipmaps = false;
|
|
|
|
var scope = this;
|
|
|
|
function update() {
|
|
|
|
requestAnimationFrame( update );
|
|
|
|
if ( video.readyState >= video.HAVE_CURRENT_DATA ) {
|
|
|
|
scope.needsUpdate = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
VideoTexture.prototype = Object.create( Texture.prototype );
|
|
VideoTexture.prototype.constructor = VideoTexture;
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
|
|
|
|
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
|
|
|
|
this.image = { width: width, height: height };
|
|
this.mipmaps = mipmaps;
|
|
|
|
// no flipping for cube textures
|
|
// (also flipping doesn't work for compressed textures )
|
|
|
|
this.flipY = false;
|
|
|
|
// can't generate mipmaps for compressed textures
|
|
// mips must be embedded in DDS files
|
|
|
|
this.generateMipmaps = false;
|
|
|
|
}
|
|
|
|
CompressedTexture.prototype = Object.create( Texture.prototype );
|
|
CompressedTexture.prototype.constructor = CompressedTexture;
|
|
|
|
CompressedTexture.prototype.isCompressedTexture = true;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
|
|
|
|
Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
|
|
|
|
this.needsUpdate = true;
|
|
|
|
}
|
|
|
|
CanvasTexture.prototype = Object.create( Texture.prototype );
|
|
CanvasTexture.prototype.constructor = CanvasTexture;
|
|
|
|
/**
|
|
* @author Matt DesLauriers / @mattdesl
|
|
* @author atix / arthursilber.de
|
|
*/
|
|
|
|
function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
|
|
|
|
format = format !== undefined ? format : DepthFormat;
|
|
|
|
if ( format !== DepthFormat && format !== DepthStencilFormat ) {
|
|
|
|
throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )
|
|
|
|
}
|
|
|
|
if ( type === undefined && format === DepthFormat ) type = UnsignedShortType;
|
|
if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
|
|
|
|
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
|
|
|
|
this.image = { width: width, height: height };
|
|
|
|
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
|
|
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
|
|
|
|
this.flipY = false;
|
|
this.generateMipmaps = false;
|
|
|
|
}
|
|
|
|
DepthTexture.prototype = Object.create( Texture.prototype );
|
|
DepthTexture.prototype.constructor = DepthTexture;
|
|
DepthTexture.prototype.isDepthTexture = true;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
function WireframeGeometry( geometry ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'WireframeGeometry';
|
|
|
|
// buffer
|
|
|
|
var vertices = [];
|
|
|
|
// helper variables
|
|
|
|
var i, j, l, o, ol;
|
|
var edge = [ 0, 0 ], edges = {}, e, edge1, edge2;
|
|
var key, keys = [ 'a', 'b', 'c' ];
|
|
var vertex;
|
|
|
|
// different logic for Geometry and BufferGeometry
|
|
|
|
if ( geometry && geometry.isGeometry ) {
|
|
|
|
// create a data structure that contains all edges without duplicates
|
|
|
|
var faces = geometry.faces;
|
|
|
|
for ( i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
for ( j = 0; j < 3; j ++ ) {
|
|
|
|
edge1 = face[ keys[ j ] ];
|
|
edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
|
|
edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
|
|
edge[ 1 ] = Math.max( edge1, edge2 );
|
|
|
|
key = edge[ 0 ] + ',' + edge[ 1 ];
|
|
|
|
if ( edges[ key ] === undefined ) {
|
|
|
|
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate vertices
|
|
|
|
for ( key in edges ) {
|
|
|
|
e = edges[ key ];
|
|
|
|
vertex = geometry.vertices[ e.index1 ];
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
vertex = geometry.vertices[ e.index2 ];
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
} else if ( geometry && geometry.isBufferGeometry ) {
|
|
|
|
var position, indices, groups;
|
|
var group, start, count;
|
|
var index1, index2;
|
|
|
|
vertex = new Vector3();
|
|
|
|
if ( geometry.index !== null ) {
|
|
|
|
// indexed BufferGeometry
|
|
|
|
position = geometry.attributes.position;
|
|
indices = geometry.index;
|
|
groups = geometry.groups;
|
|
|
|
if ( groups.length === 0 ) {
|
|
|
|
groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
|
|
|
|
}
|
|
|
|
// create a data structure that contains all eges without duplicates
|
|
|
|
for ( o = 0, ol = groups.length; o < ol; ++ o ) {
|
|
|
|
group = groups[ o ];
|
|
|
|
start = group.start;
|
|
count = group.count;
|
|
|
|
for ( i = start, l = ( start + count ); i < l; i += 3 ) {
|
|
|
|
for ( j = 0; j < 3; j ++ ) {
|
|
|
|
edge1 = indices.getX( i + j );
|
|
edge2 = indices.getX( i + ( j + 1 ) % 3 );
|
|
edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
|
|
edge[ 1 ] = Math.max( edge1, edge2 );
|
|
|
|
key = edge[ 0 ] + ',' + edge[ 1 ];
|
|
|
|
if ( edges[ key ] === undefined ) {
|
|
|
|
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate vertices
|
|
|
|
for ( key in edges ) {
|
|
|
|
e = edges[ key ];
|
|
|
|
vertex.fromBufferAttribute( position, e.index1 );
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
vertex.fromBufferAttribute( position, e.index2 );
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// non-indexed BufferGeometry
|
|
|
|
position = geometry.attributes.position;
|
|
|
|
for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
|
|
|
|
for ( j = 0; j < 3; j ++ ) {
|
|
|
|
// three edges per triangle, an edge is represented as (index1, index2)
|
|
// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
|
|
|
|
index1 = 3 * i + j;
|
|
vertex.fromBufferAttribute( position, index1 );
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
index2 = 3 * i + ( ( j + 1 ) % 3 );
|
|
vertex.fromBufferAttribute( position, index2 );
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
|
|
}
|
|
|
|
WireframeGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
WireframeGeometry.prototype.constructor = WireframeGeometry;
|
|
|
|
/**
|
|
* @author zz85 / https://github.com/zz85
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*
|
|
* Parametric Surfaces Geometry
|
|
* based on the brilliant article by @prideout http://prideout.net/blog/?p=44
|
|
*/
|
|
|
|
// ParametricGeometry
|
|
|
|
function ParametricGeometry( func, slices, stacks ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'ParametricGeometry';
|
|
|
|
this.parameters = {
|
|
func: func,
|
|
slices: slices,
|
|
stacks: stacks
|
|
};
|
|
|
|
this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
ParametricGeometry.prototype = Object.create( Geometry.prototype );
|
|
ParametricGeometry.prototype.constructor = ParametricGeometry;
|
|
|
|
// ParametricBufferGeometry
|
|
|
|
function ParametricBufferGeometry( func, slices, stacks ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'ParametricBufferGeometry';
|
|
|
|
this.parameters = {
|
|
func: func,
|
|
slices: slices,
|
|
stacks: stacks
|
|
};
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
var EPS = 0.00001;
|
|
|
|
var normal = new Vector3();
|
|
|
|
var p0 = new Vector3(), p1 = new Vector3();
|
|
var pu = new Vector3(), pv = new Vector3();
|
|
|
|
var i, j;
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
var sliceCount = slices + 1;
|
|
|
|
for ( i = 0; i <= stacks; i ++ ) {
|
|
|
|
var v = i / stacks;
|
|
|
|
for ( j = 0; j <= slices; j ++ ) {
|
|
|
|
var u = j / slices;
|
|
|
|
// vertex
|
|
|
|
p0 = func( u, v, p0 );
|
|
vertices.push( p0.x, p0.y, p0.z );
|
|
|
|
// normal
|
|
|
|
// approximate tangent vectors via finite differences
|
|
|
|
if ( u - EPS >= 0 ) {
|
|
|
|
p1 = func( u - EPS, v, p1 );
|
|
pu.subVectors( p0, p1 );
|
|
|
|
} else {
|
|
|
|
p1 = func( u + EPS, v, p1 );
|
|
pu.subVectors( p1, p0 );
|
|
|
|
}
|
|
|
|
if ( v - EPS >= 0 ) {
|
|
|
|
p1 = func( u, v - EPS, p1 );
|
|
pv.subVectors( p0, p1 );
|
|
|
|
} else {
|
|
|
|
p1 = func( u, v + EPS, p1 );
|
|
pv.subVectors( p1, p0 );
|
|
|
|
}
|
|
|
|
// cross product of tangent vectors returns surface normal
|
|
|
|
normal.crossVectors( pu, pv ).normalize();
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// uv
|
|
|
|
uvs.push( u, v );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate indices
|
|
|
|
for ( i = 0; i < stacks; i ++ ) {
|
|
|
|
for ( j = 0; j < slices; j ++ ) {
|
|
|
|
var a = i * sliceCount + j;
|
|
var b = i * sliceCount + j + 1;
|
|
var c = ( i + 1 ) * sliceCount + j + 1;
|
|
var d = ( i + 1 ) * sliceCount + j;
|
|
|
|
// faces one and two
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
|
|
|
|
/**
|
|
* @author clockworkgeek / https://github.com/clockworkgeek
|
|
* @author timothypratley / https://github.com/timothypratley
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// PolyhedronGeometry
|
|
|
|
function PolyhedronGeometry( vertices, indices, radius, detail ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'PolyhedronGeometry';
|
|
|
|
this.parameters = {
|
|
vertices: vertices,
|
|
indices: indices,
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
PolyhedronGeometry.prototype = Object.create( Geometry.prototype );
|
|
PolyhedronGeometry.prototype.constructor = PolyhedronGeometry;
|
|
|
|
// PolyhedronBufferGeometry
|
|
|
|
function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'PolyhedronBufferGeometry';
|
|
|
|
this.parameters = {
|
|
vertices: vertices,
|
|
indices: indices,
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
radius = radius || 1;
|
|
detail = detail || 0;
|
|
|
|
// default buffer data
|
|
|
|
var vertexBuffer = [];
|
|
var uvBuffer = [];
|
|
|
|
// the subdivision creates the vertex buffer data
|
|
|
|
subdivide( detail );
|
|
|
|
// all vertices should lie on a conceptual sphere with a given radius
|
|
|
|
appplyRadius( radius );
|
|
|
|
// finally, create the uv data
|
|
|
|
generateUVs();
|
|
|
|
// build non-indexed geometry
|
|
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
|
|
this.normalizeNormals();
|
|
|
|
// helper functions
|
|
|
|
function subdivide( detail ) {
|
|
|
|
var a = new Vector3();
|
|
var b = new Vector3();
|
|
var c = new Vector3();
|
|
|
|
// iterate over all faces and apply a subdivison with the given detail value
|
|
|
|
for ( var i = 0; i < indices.length; i += 3 ) {
|
|
|
|
// get the vertices of the face
|
|
|
|
getVertexByIndex( indices[ i + 0 ], a );
|
|
getVertexByIndex( indices[ i + 1 ], b );
|
|
getVertexByIndex( indices[ i + 2 ], c );
|
|
|
|
// perform subdivision
|
|
|
|
subdivideFace( a, b, c, detail );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function subdivideFace( a, b, c, detail ) {
|
|
|
|
var cols = Math.pow( 2, detail );
|
|
|
|
// we use this multidimensional array as a data structure for creating the subdivision
|
|
|
|
var v = [];
|
|
|
|
var i, j;
|
|
|
|
// construct all of the vertices for this subdivision
|
|
|
|
for ( i = 0; i <= cols; i ++ ) {
|
|
|
|
v[ i ] = [];
|
|
|
|
var aj = a.clone().lerp( c, i / cols );
|
|
var bj = b.clone().lerp( c, i / cols );
|
|
|
|
var rows = cols - i;
|
|
|
|
for ( j = 0; j <= rows; j ++ ) {
|
|
|
|
if ( j === 0 && i === cols ) {
|
|
|
|
v[ i ][ j ] = aj;
|
|
|
|
} else {
|
|
|
|
v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// construct all of the faces
|
|
|
|
for ( i = 0; i < cols; i ++ ) {
|
|
|
|
for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
|
|
|
|
var k = Math.floor( j / 2 );
|
|
|
|
if ( j % 2 === 0 ) {
|
|
|
|
pushVertex( v[ i ][ k + 1 ] );
|
|
pushVertex( v[ i + 1 ][ k ] );
|
|
pushVertex( v[ i ][ k ] );
|
|
|
|
} else {
|
|
|
|
pushVertex( v[ i ][ k + 1 ] );
|
|
pushVertex( v[ i + 1 ][ k + 1 ] );
|
|
pushVertex( v[ i + 1 ][ k ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function appplyRadius( radius ) {
|
|
|
|
var vertex = new Vector3();
|
|
|
|
// iterate over the entire buffer and apply the radius to each vertex
|
|
|
|
for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
|
|
|
|
vertex.x = vertexBuffer[ i + 0 ];
|
|
vertex.y = vertexBuffer[ i + 1 ];
|
|
vertex.z = vertexBuffer[ i + 2 ];
|
|
|
|
vertex.normalize().multiplyScalar( radius );
|
|
|
|
vertexBuffer[ i + 0 ] = vertex.x;
|
|
vertexBuffer[ i + 1 ] = vertex.y;
|
|
vertexBuffer[ i + 2 ] = vertex.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function generateUVs() {
|
|
|
|
var vertex = new Vector3();
|
|
|
|
for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
|
|
|
|
vertex.x = vertexBuffer[ i + 0 ];
|
|
vertex.y = vertexBuffer[ i + 1 ];
|
|
vertex.z = vertexBuffer[ i + 2 ];
|
|
|
|
var u = azimuth( vertex ) / 2 / Math.PI + 0.5;
|
|
var v = inclination( vertex ) / Math.PI + 0.5;
|
|
uvBuffer.push( u, 1 - v );
|
|
|
|
}
|
|
|
|
correctUVs();
|
|
|
|
correctSeam();
|
|
|
|
}
|
|
|
|
function correctSeam() {
|
|
|
|
// handle case when face straddles the seam, see #3269
|
|
|
|
for ( var i = 0; i < uvBuffer.length; i += 6 ) {
|
|
|
|
// uv data of a single face
|
|
|
|
var x0 = uvBuffer[ i + 0 ];
|
|
var x1 = uvBuffer[ i + 2 ];
|
|
var x2 = uvBuffer[ i + 4 ];
|
|
|
|
var max = Math.max( x0, x1, x2 );
|
|
var min = Math.min( x0, x1, x2 );
|
|
|
|
// 0.9 is somewhat arbitrary
|
|
|
|
if ( max > 0.9 && min < 0.1 ) {
|
|
|
|
if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;
|
|
if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;
|
|
if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function pushVertex( vertex ) {
|
|
|
|
vertexBuffer.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
function getVertexByIndex( index, vertex ) {
|
|
|
|
var stride = index * 3;
|
|
|
|
vertex.x = vertices[ stride + 0 ];
|
|
vertex.y = vertices[ stride + 1 ];
|
|
vertex.z = vertices[ stride + 2 ];
|
|
|
|
}
|
|
|
|
function correctUVs() {
|
|
|
|
var a = new Vector3();
|
|
var b = new Vector3();
|
|
var c = new Vector3();
|
|
|
|
var centroid = new Vector3();
|
|
|
|
var uvA = new Vector2();
|
|
var uvB = new Vector2();
|
|
var uvC = new Vector2();
|
|
|
|
for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
|
|
|
|
a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
|
|
b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
|
|
c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
|
|
|
|
uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
|
|
uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
|
|
uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
|
|
|
|
centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
|
|
|
|
var azi = azimuth( centroid );
|
|
|
|
correctUV( uvA, j + 0, a, azi );
|
|
correctUV( uvB, j + 2, b, azi );
|
|
correctUV( uvC, j + 4, c, azi );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function correctUV( uv, stride, vector, azimuth ) {
|
|
|
|
if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
|
|
|
|
uvBuffer[ stride ] = uv.x - 1;
|
|
|
|
}
|
|
|
|
if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
|
|
|
|
uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Angle around the Y axis, counter-clockwise when looking from above.
|
|
|
|
function azimuth( vector ) {
|
|
|
|
return Math.atan2( vector.z, - vector.x );
|
|
|
|
}
|
|
|
|
|
|
// Angle above the XZ plane.
|
|
|
|
function inclination( vector ) {
|
|
|
|
return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;
|
|
|
|
/**
|
|
* @author timothypratley / https://github.com/timothypratley
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// TetrahedronGeometry
|
|
|
|
function TetrahedronGeometry( radius, detail ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'TetrahedronGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
TetrahedronGeometry.prototype = Object.create( Geometry.prototype );
|
|
TetrahedronGeometry.prototype.constructor = TetrahedronGeometry;
|
|
|
|
// TetrahedronBufferGeometry
|
|
|
|
function TetrahedronBufferGeometry( radius, detail ) {
|
|
|
|
var vertices = [
|
|
1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
|
|
];
|
|
|
|
var indices = [
|
|
2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
|
|
];
|
|
|
|
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
|
|
|
|
this.type = 'TetrahedronBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
}
|
|
|
|
TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
|
|
TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;
|
|
|
|
/**
|
|
* @author timothypratley / https://github.com/timothypratley
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// OctahedronGeometry
|
|
|
|
function OctahedronGeometry( radius, detail ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'OctahedronGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
OctahedronGeometry.prototype = Object.create( Geometry.prototype );
|
|
OctahedronGeometry.prototype.constructor = OctahedronGeometry;
|
|
|
|
// OctahedronBufferGeometry
|
|
|
|
function OctahedronBufferGeometry( radius, detail ) {
|
|
|
|
var vertices = [
|
|
1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1
|
|
];
|
|
|
|
var indices = [
|
|
0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2
|
|
];
|
|
|
|
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
|
|
|
|
this.type = 'OctahedronBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
}
|
|
|
|
OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
|
|
OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;
|
|
|
|
/**
|
|
* @author timothypratley / https://github.com/timothypratley
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// IcosahedronGeometry
|
|
|
|
function IcosahedronGeometry( radius, detail ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'IcosahedronGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
IcosahedronGeometry.prototype = Object.create( Geometry.prototype );
|
|
IcosahedronGeometry.prototype.constructor = IcosahedronGeometry;
|
|
|
|
// IcosahedronBufferGeometry
|
|
|
|
function IcosahedronBufferGeometry( radius, detail ) {
|
|
|
|
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
|
|
|
|
var vertices = [
|
|
- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
|
|
0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
|
|
t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
|
|
];
|
|
|
|
var indices = [
|
|
0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
|
|
1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
|
|
3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
|
|
4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
|
|
];
|
|
|
|
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
|
|
|
|
this.type = 'IcosahedronBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
}
|
|
|
|
IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
|
|
IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;
|
|
|
|
/**
|
|
* @author Abe Pazos / https://hamoid.com
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// DodecahedronGeometry
|
|
|
|
function DodecahedronGeometry( radius, detail ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'DodecahedronGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
DodecahedronGeometry.prototype = Object.create( Geometry.prototype );
|
|
DodecahedronGeometry.prototype.constructor = DodecahedronGeometry;
|
|
|
|
// DodecahedronBufferGeometry
|
|
|
|
function DodecahedronBufferGeometry( radius, detail ) {
|
|
|
|
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
|
|
var r = 1 / t;
|
|
|
|
var vertices = [
|
|
|
|
// (±1, ±1, ±1)
|
|
- 1, - 1, - 1, - 1, - 1, 1,
|
|
- 1, 1, - 1, - 1, 1, 1,
|
|
1, - 1, - 1, 1, - 1, 1,
|
|
1, 1, - 1, 1, 1, 1,
|
|
|
|
// (0, ±1/φ, ±φ)
|
|
0, - r, - t, 0, - r, t,
|
|
0, r, - t, 0, r, t,
|
|
|
|
// (±1/φ, ±φ, 0)
|
|
- r, - t, 0, - r, t, 0,
|
|
r, - t, 0, r, t, 0,
|
|
|
|
// (±φ, 0, ±1/φ)
|
|
- t, 0, - r, t, 0, - r,
|
|
- t, 0, r, t, 0, r
|
|
];
|
|
|
|
var indices = [
|
|
3, 11, 7, 3, 7, 15, 3, 15, 13,
|
|
7, 19, 17, 7, 17, 6, 7, 6, 15,
|
|
17, 4, 8, 17, 8, 10, 17, 10, 6,
|
|
8, 0, 16, 8, 16, 2, 8, 2, 10,
|
|
0, 12, 1, 0, 1, 18, 0, 18, 16,
|
|
6, 10, 2, 6, 2, 13, 6, 13, 15,
|
|
2, 16, 18, 2, 18, 3, 2, 3, 13,
|
|
18, 1, 9, 18, 9, 11, 18, 11, 3,
|
|
4, 14, 12, 4, 12, 0, 4, 0, 8,
|
|
11, 9, 5, 11, 5, 19, 11, 19, 7,
|
|
19, 5, 14, 19, 14, 4, 19, 4, 17,
|
|
1, 12, 14, 1, 14, 5, 1, 5, 9
|
|
];
|
|
|
|
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
|
|
|
|
this.type = 'DodecahedronBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
detail: detail
|
|
};
|
|
|
|
}
|
|
|
|
DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
|
|
DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;
|
|
|
|
/**
|
|
* @author oosmoxiecode / https://github.com/oosmoxiecode
|
|
* @author WestLangley / https://github.com/WestLangley
|
|
* @author zz85 / https://github.com/zz85
|
|
* @author miningold / https://github.com/miningold
|
|
* @author jonobr1 / https://github.com/jonobr1
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*
|
|
*/
|
|
|
|
// TubeGeometry
|
|
|
|
function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'TubeGeometry';
|
|
|
|
this.parameters = {
|
|
path: path,
|
|
tubularSegments: tubularSegments,
|
|
radius: radius,
|
|
radialSegments: radialSegments,
|
|
closed: closed
|
|
};
|
|
|
|
if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );
|
|
|
|
var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
|
|
|
|
// expose internals
|
|
|
|
this.tangents = bufferGeometry.tangents;
|
|
this.normals = bufferGeometry.normals;
|
|
this.binormals = bufferGeometry.binormals;
|
|
|
|
// create geometry
|
|
|
|
this.fromBufferGeometry( bufferGeometry );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
TubeGeometry.prototype = Object.create( Geometry.prototype );
|
|
TubeGeometry.prototype.constructor = TubeGeometry;
|
|
|
|
// TubeBufferGeometry
|
|
|
|
function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'TubeBufferGeometry';
|
|
|
|
this.parameters = {
|
|
path: path,
|
|
tubularSegments: tubularSegments,
|
|
radius: radius,
|
|
radialSegments: radialSegments,
|
|
closed: closed
|
|
};
|
|
|
|
tubularSegments = tubularSegments || 64;
|
|
radius = radius || 1;
|
|
radialSegments = radialSegments || 8;
|
|
closed = closed || false;
|
|
|
|
var frames = path.computeFrenetFrames( tubularSegments, closed );
|
|
|
|
// expose internals
|
|
|
|
this.tangents = frames.tangents;
|
|
this.normals = frames.normals;
|
|
this.binormals = frames.binormals;
|
|
|
|
// helper variables
|
|
|
|
var vertex = new Vector3();
|
|
var normal = new Vector3();
|
|
var uv = new Vector2();
|
|
|
|
var i, j;
|
|
|
|
// buffer
|
|
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
var indices = [];
|
|
|
|
// create buffer data
|
|
|
|
generateBufferData();
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
// functions
|
|
|
|
function generateBufferData() {
|
|
|
|
for ( i = 0; i < tubularSegments; i ++ ) {
|
|
|
|
generateSegment( i );
|
|
|
|
}
|
|
|
|
// if the geometry is not closed, generate the last row of vertices and normals
|
|
// at the regular position on the given path
|
|
//
|
|
// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
|
|
|
|
generateSegment( ( closed === false ) ? tubularSegments : 0 );
|
|
|
|
// uvs are generated in a separate function.
|
|
// this makes it easy compute correct values for closed geometries
|
|
|
|
generateUVs();
|
|
|
|
// finally create faces
|
|
|
|
generateIndices();
|
|
|
|
}
|
|
|
|
function generateSegment( i ) {
|
|
|
|
// we use getPointAt to sample evenly distributed points from the given path
|
|
|
|
var P = path.getPointAt( i / tubularSegments );
|
|
|
|
// retrieve corresponding normal and binormal
|
|
|
|
var N = frames.normals[ i ];
|
|
var B = frames.binormals[ i ];
|
|
|
|
// generate normals and vertices for the current segment
|
|
|
|
for ( j = 0; j <= radialSegments; j ++ ) {
|
|
|
|
var v = j / radialSegments * Math.PI * 2;
|
|
|
|
var sin = Math.sin( v );
|
|
var cos = - Math.cos( v );
|
|
|
|
// normal
|
|
|
|
normal.x = ( cos * N.x + sin * B.x );
|
|
normal.y = ( cos * N.y + sin * B.y );
|
|
normal.z = ( cos * N.z + sin * B.z );
|
|
normal.normalize();
|
|
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// vertex
|
|
|
|
vertex.x = P.x + radius * normal.x;
|
|
vertex.y = P.y + radius * normal.y;
|
|
vertex.z = P.z + radius * normal.z;
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function generateIndices() {
|
|
|
|
for ( j = 1; j <= tubularSegments; j ++ ) {
|
|
|
|
for ( i = 1; i <= radialSegments; i ++ ) {
|
|
|
|
var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
|
|
var b = ( radialSegments + 1 ) * j + ( i - 1 );
|
|
var c = ( radialSegments + 1 ) * j + i;
|
|
var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function generateUVs() {
|
|
|
|
for ( i = 0; i <= tubularSegments; i ++ ) {
|
|
|
|
for ( j = 0; j <= radialSegments; j ++ ) {
|
|
|
|
uv.x = i / tubularSegments;
|
|
uv.y = j / radialSegments;
|
|
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
TubeBufferGeometry.prototype.constructor = TubeBufferGeometry;
|
|
|
|
/**
|
|
* @author oosmoxiecode
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*
|
|
* based on http://www.blackpawn.com/texts/pqtorus/
|
|
*/
|
|
|
|
// TorusKnotGeometry
|
|
|
|
function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'TorusKnotGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
tube: tube,
|
|
tubularSegments: tubularSegments,
|
|
radialSegments: radialSegments,
|
|
p: p,
|
|
q: q
|
|
};
|
|
|
|
if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );
|
|
|
|
this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
TorusKnotGeometry.prototype = Object.create( Geometry.prototype );
|
|
TorusKnotGeometry.prototype.constructor = TorusKnotGeometry;
|
|
|
|
// TorusKnotBufferGeometry
|
|
|
|
function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'TorusKnotBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
tube: tube,
|
|
tubularSegments: tubularSegments,
|
|
radialSegments: radialSegments,
|
|
p: p,
|
|
q: q
|
|
};
|
|
|
|
radius = radius || 100;
|
|
tube = tube || 40;
|
|
tubularSegments = Math.floor( tubularSegments ) || 64;
|
|
radialSegments = Math.floor( radialSegments ) || 8;
|
|
p = p || 2;
|
|
q = q || 3;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var i, j;
|
|
|
|
var vertex = new Vector3();
|
|
var normal = new Vector3();
|
|
|
|
var P1 = new Vector3();
|
|
var P2 = new Vector3();
|
|
|
|
var B = new Vector3();
|
|
var T = new Vector3();
|
|
var N = new Vector3();
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( i = 0; i <= tubularSegments; ++ i ) {
|
|
|
|
// the radian "u" is used to calculate the position on the torus curve of the current tubular segement
|
|
|
|
var u = i / tubularSegments * p * Math.PI * 2;
|
|
|
|
// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
|
|
// these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
|
|
|
|
calculatePositionOnCurve( u, p, q, radius, P1 );
|
|
calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
|
|
|
|
// calculate orthonormal basis
|
|
|
|
T.subVectors( P2, P1 );
|
|
N.addVectors( P2, P1 );
|
|
B.crossVectors( T, N );
|
|
N.crossVectors( B, T );
|
|
|
|
// normalize B, N. T can be ignored, we don't use it
|
|
|
|
B.normalize();
|
|
N.normalize();
|
|
|
|
for ( j = 0; j <= radialSegments; ++ j ) {
|
|
|
|
// now calculate the vertices. they are nothing more than an extrusion of the torus curve.
|
|
// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
|
|
|
|
var v = j / radialSegments * Math.PI * 2;
|
|
var cx = - tube * Math.cos( v );
|
|
var cy = tube * Math.sin( v );
|
|
|
|
// now calculate the final vertex position.
|
|
// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve
|
|
|
|
vertex.x = P1.x + ( cx * N.x + cy * B.x );
|
|
vertex.y = P1.y + ( cx * N.y + cy * B.y );
|
|
vertex.z = P1.z + ( cx * N.z + cy * B.z );
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
|
|
|
|
normal.subVectors( vertex, P1 ).normalize();
|
|
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// uv
|
|
|
|
uvs.push( i / tubularSegments );
|
|
uvs.push( j / radialSegments );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate indices
|
|
|
|
for ( j = 1; j <= tubularSegments; j ++ ) {
|
|
|
|
for ( i = 1; i <= radialSegments; i ++ ) {
|
|
|
|
// indices
|
|
|
|
var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
|
|
var b = ( radialSegments + 1 ) * j + ( i - 1 );
|
|
var c = ( radialSegments + 1 ) * j + i;
|
|
var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
// this function calculates the current position on the torus curve
|
|
|
|
function calculatePositionOnCurve( u, p, q, radius, position ) {
|
|
|
|
var cu = Math.cos( u );
|
|
var su = Math.sin( u );
|
|
var quOverP = q / p * u;
|
|
var cs = Math.cos( quOverP );
|
|
|
|
position.x = radius * ( 2 + cs ) * 0.5 * cu;
|
|
position.y = radius * ( 2 + cs ) * su * 0.5;
|
|
position.z = radius * Math.sin( quOverP ) * 0.5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;
|
|
|
|
/**
|
|
* @author oosmoxiecode
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// TorusGeometry
|
|
|
|
function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'TorusGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
tube: tube,
|
|
radialSegments: radialSegments,
|
|
tubularSegments: tubularSegments,
|
|
arc: arc
|
|
};
|
|
|
|
this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
TorusGeometry.prototype = Object.create( Geometry.prototype );
|
|
TorusGeometry.prototype.constructor = TorusGeometry;
|
|
|
|
// TorusBufferGeometry
|
|
|
|
function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'TorusBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
tube: tube,
|
|
radialSegments: radialSegments,
|
|
tubularSegments: tubularSegments,
|
|
arc: arc
|
|
};
|
|
|
|
radius = radius || 100;
|
|
tube = tube || 40;
|
|
radialSegments = Math.floor( radialSegments ) || 8;
|
|
tubularSegments = Math.floor( tubularSegments ) || 6;
|
|
arc = arc || Math.PI * 2;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var center = new Vector3();
|
|
var vertex = new Vector3();
|
|
var normal = new Vector3();
|
|
|
|
var j, i;
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( j = 0; j <= radialSegments; j ++ ) {
|
|
|
|
for ( i = 0; i <= tubularSegments; i ++ ) {
|
|
|
|
var u = i / tubularSegments * arc;
|
|
var v = j / radialSegments * Math.PI * 2;
|
|
|
|
// vertex
|
|
|
|
vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
|
|
vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
|
|
vertex.z = tube * Math.sin( v );
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
center.x = radius * Math.cos( u );
|
|
center.y = radius * Math.sin( u );
|
|
normal.subVectors( vertex, center ).normalize();
|
|
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// uv
|
|
|
|
uvs.push( i / tubularSegments );
|
|
uvs.push( j / radialSegments );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate indices
|
|
|
|
for ( j = 1; j <= radialSegments; j ++ ) {
|
|
|
|
for ( i = 1; i <= tubularSegments; i ++ ) {
|
|
|
|
// indices
|
|
|
|
var a = ( tubularSegments + 1 ) * j + i - 1;
|
|
var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
|
|
var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
|
|
var d = ( tubularSegments + 1 ) * j + i;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
*/
|
|
|
|
var ShapeUtils = {
|
|
|
|
// calculate area of the contour polygon
|
|
|
|
area: function ( contour ) {
|
|
|
|
var n = contour.length;
|
|
var a = 0.0;
|
|
|
|
for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
|
|
|
|
a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
|
|
|
|
}
|
|
|
|
return a * 0.5;
|
|
|
|
},
|
|
|
|
triangulate: ( function () {
|
|
|
|
/**
|
|
* This code is a quick port of code written in C++ which was submitted to
|
|
* flipcode.com by John W. Ratcliff // July 22, 2000
|
|
* See original code and more information here:
|
|
* http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
|
|
*
|
|
* ported to actionscript by Zevan Rosser
|
|
* www.actionsnippet.com
|
|
*
|
|
* ported to javascript by Joshua Koo
|
|
* http://www.lab4games.net/zz85/blog
|
|
*
|
|
*/
|
|
|
|
function snip( contour, u, v, w, n, verts ) {
|
|
|
|
var p;
|
|
var ax, ay, bx, by;
|
|
var cx, cy, px, py;
|
|
|
|
ax = contour[ verts[ u ] ].x;
|
|
ay = contour[ verts[ u ] ].y;
|
|
|
|
bx = contour[ verts[ v ] ].x;
|
|
by = contour[ verts[ v ] ].y;
|
|
|
|
cx = contour[ verts[ w ] ].x;
|
|
cy = contour[ verts[ w ] ].y;
|
|
|
|
if ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;
|
|
|
|
var aX, aY, bX, bY, cX, cY;
|
|
var apx, apy, bpx, bpy, cpx, cpy;
|
|
var cCROSSap, bCROSScp, aCROSSbp;
|
|
|
|
aX = cx - bx; aY = cy - by;
|
|
bX = ax - cx; bY = ay - cy;
|
|
cX = bx - ax; cY = by - ay;
|
|
|
|
for ( p = 0; p < n; p ++ ) {
|
|
|
|
px = contour[ verts[ p ] ].x;
|
|
py = contour[ verts[ p ] ].y;
|
|
|
|
if ( ( ( px === ax ) && ( py === ay ) ) ||
|
|
( ( px === bx ) && ( py === by ) ) ||
|
|
( ( px === cx ) && ( py === cy ) ) ) continue;
|
|
|
|
apx = px - ax; apy = py - ay;
|
|
bpx = px - bx; bpy = py - by;
|
|
cpx = px - cx; cpy = py - cy;
|
|
|
|
// see if p is inside triangle abc
|
|
|
|
aCROSSbp = aX * bpy - aY * bpx;
|
|
cCROSSap = cX * apy - cY * apx;
|
|
bCROSScp = bX * cpy - bY * cpx;
|
|
|
|
if ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// takes in an contour array and returns
|
|
|
|
return function triangulate( contour, indices ) {
|
|
|
|
var n = contour.length;
|
|
|
|
if ( n < 3 ) return null;
|
|
|
|
var result = [],
|
|
verts = [],
|
|
vertIndices = [];
|
|
|
|
/* we want a counter-clockwise polygon in verts */
|
|
|
|
var u, v, w;
|
|
|
|
if ( ShapeUtils.area( contour ) > 0.0 ) {
|
|
|
|
for ( v = 0; v < n; v ++ ) verts[ v ] = v;
|
|
|
|
} else {
|
|
|
|
for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
|
|
|
|
}
|
|
|
|
var nv = n;
|
|
|
|
/* remove nv - 2 vertices, creating 1 triangle every time */
|
|
|
|
var count = 2 * nv; /* error detection */
|
|
|
|
for ( v = nv - 1; nv > 2; ) {
|
|
|
|
/* if we loop, it is probably a non-simple polygon */
|
|
|
|
if ( ( count -- ) <= 0 ) {
|
|
|
|
//** Triangulate: ERROR - probable bad polygon!
|
|
|
|
//throw ( "Warning, unable to triangulate polygon!" );
|
|
//return null;
|
|
// Sometimes warning is fine, especially polygons are triangulated in reverse.
|
|
console.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );
|
|
|
|
if ( indices ) return vertIndices;
|
|
return result;
|
|
|
|
}
|
|
|
|
/* three consecutive vertices in current polygon, <u,v,w> */
|
|
|
|
u = v; if ( nv <= u ) u = 0; /* previous */
|
|
v = u + 1; if ( nv <= v ) v = 0; /* new v */
|
|
w = v + 1; if ( nv <= w ) w = 0; /* next */
|
|
|
|
if ( snip( contour, u, v, w, nv, verts ) ) {
|
|
|
|
var a, b, c, s, t;
|
|
|
|
/* true names of the vertices */
|
|
|
|
a = verts[ u ];
|
|
b = verts[ v ];
|
|
c = verts[ w ];
|
|
|
|
/* output Triangle */
|
|
|
|
result.push( [ contour[ a ],
|
|
contour[ b ],
|
|
contour[ c ] ] );
|
|
|
|
|
|
vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
|
|
|
|
/* remove v from the remaining polygon */
|
|
|
|
for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
|
|
|
|
verts[ s ] = verts[ t ];
|
|
|
|
}
|
|
|
|
nv --;
|
|
|
|
/* reset error detection counter */
|
|
|
|
count = 2 * nv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( indices ) return vertIndices;
|
|
return result;
|
|
|
|
}
|
|
|
|
} )(),
|
|
|
|
triangulateShape: function ( contour, holes ) {
|
|
|
|
function removeDupEndPts(points) {
|
|
|
|
var l = points.length;
|
|
|
|
if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
|
|
|
|
points.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
removeDupEndPts( contour );
|
|
holes.forEach( removeDupEndPts );
|
|
|
|
function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
|
|
|
|
// inOtherPt needs to be collinear to the inSegment
|
|
if ( inSegPt1.x !== inSegPt2.x ) {
|
|
|
|
if ( inSegPt1.x < inSegPt2.x ) {
|
|
|
|
return ( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );
|
|
|
|
} else {
|
|
|
|
return ( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( inSegPt1.y < inSegPt2.y ) {
|
|
|
|
return ( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );
|
|
|
|
} else {
|
|
|
|
return ( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {
|
|
|
|
var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;
|
|
var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;
|
|
|
|
var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;
|
|
var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;
|
|
|
|
var limit = seg1dy * seg2dx - seg1dx * seg2dy;
|
|
var perpSeg1 = seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;
|
|
|
|
if ( Math.abs( limit ) > Number.EPSILON ) {
|
|
|
|
// not parallel
|
|
|
|
var perpSeg2;
|
|
if ( limit > 0 ) {
|
|
|
|
if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return [];
|
|
perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
|
|
if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return [];
|
|
|
|
} else {
|
|
|
|
if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return [];
|
|
perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
|
|
if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return [];
|
|
|
|
}
|
|
|
|
// i.e. to reduce rounding errors
|
|
// intersection at endpoint of segment#1?
|
|
if ( perpSeg2 === 0 ) {
|
|
|
|
if ( ( inExcludeAdjacentSegs ) &&
|
|
( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
|
|
return [ inSeg1Pt1 ];
|
|
|
|
}
|
|
if ( perpSeg2 === limit ) {
|
|
|
|
if ( ( inExcludeAdjacentSegs ) &&
|
|
( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
|
|
return [ inSeg1Pt2 ];
|
|
|
|
}
|
|
// intersection at endpoint of segment#2?
|
|
if ( perpSeg1 === 0 ) return [ inSeg2Pt1 ];
|
|
if ( perpSeg1 === limit ) return [ inSeg2Pt2 ];
|
|
|
|
// return real intersection point
|
|
var factorSeg1 = perpSeg2 / limit;
|
|
return [ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,
|
|
y: inSeg1Pt1.y + factorSeg1 * seg1dy } ];
|
|
|
|
} else {
|
|
|
|
// parallel or collinear
|
|
if ( ( perpSeg1 !== 0 ) ||
|
|
( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) return [];
|
|
|
|
// they are collinear or degenerate
|
|
var seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) ); // segment1 is just a point?
|
|
var seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) ); // segment2 is just a point?
|
|
// both segments are points
|
|
if ( seg1Pt && seg2Pt ) {
|
|
|
|
if ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||
|
|
( inSeg1Pt1.y !== inSeg2Pt1.y ) ) return []; // they are distinct points
|
|
return [ inSeg1Pt1 ]; // they are the same point
|
|
|
|
}
|
|
// segment#1 is a single point
|
|
if ( seg1Pt ) {
|
|
|
|
if ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return []; // but not in segment#2
|
|
return [ inSeg1Pt1 ];
|
|
|
|
}
|
|
// segment#2 is a single point
|
|
if ( seg2Pt ) {
|
|
|
|
if ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return []; // but not in segment#1
|
|
return [ inSeg2Pt1 ];
|
|
|
|
}
|
|
|
|
// they are collinear segments, which might overlap
|
|
var seg1min, seg1max, seg1minVal, seg1maxVal;
|
|
var seg2min, seg2max, seg2minVal, seg2maxVal;
|
|
if ( seg1dx !== 0 ) {
|
|
|
|
// the segments are NOT on a vertical line
|
|
if ( inSeg1Pt1.x < inSeg1Pt2.x ) {
|
|
|
|
seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;
|
|
seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;
|
|
|
|
} else {
|
|
|
|
seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;
|
|
seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;
|
|
|
|
}
|
|
if ( inSeg2Pt1.x < inSeg2Pt2.x ) {
|
|
|
|
seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;
|
|
seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;
|
|
|
|
} else {
|
|
|
|
seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;
|
|
seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// the segments are on a vertical line
|
|
if ( inSeg1Pt1.y < inSeg1Pt2.y ) {
|
|
|
|
seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;
|
|
seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;
|
|
|
|
} else {
|
|
|
|
seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;
|
|
seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;
|
|
|
|
}
|
|
if ( inSeg2Pt1.y < inSeg2Pt2.y ) {
|
|
|
|
seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;
|
|
seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;
|
|
|
|
} else {
|
|
|
|
seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;
|
|
seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;
|
|
|
|
}
|
|
|
|
}
|
|
if ( seg1minVal <= seg2minVal ) {
|
|
|
|
if ( seg1maxVal < seg2minVal ) return [];
|
|
if ( seg1maxVal === seg2minVal ) {
|
|
|
|
if ( inExcludeAdjacentSegs ) return [];
|
|
return [ seg2min ];
|
|
|
|
}
|
|
if ( seg1maxVal <= seg2maxVal ) return [ seg2min, seg1max ];
|
|
return [ seg2min, seg2max ];
|
|
|
|
} else {
|
|
|
|
if ( seg1minVal > seg2maxVal ) return [];
|
|
if ( seg1minVal === seg2maxVal ) {
|
|
|
|
if ( inExcludeAdjacentSegs ) return [];
|
|
return [ seg1min ];
|
|
|
|
}
|
|
if ( seg1maxVal <= seg2maxVal ) return [ seg1min, seg1max ];
|
|
return [ seg1min, seg2max ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {
|
|
|
|
// The order of legs is important
|
|
|
|
// translation of all points, so that Vertex is at (0,0)
|
|
var legFromPtX = inLegFromPt.x - inVertex.x, legFromPtY = inLegFromPt.y - inVertex.y;
|
|
var legToPtX = inLegToPt.x - inVertex.x, legToPtY = inLegToPt.y - inVertex.y;
|
|
var otherPtX = inOtherPt.x - inVertex.x, otherPtY = inOtherPt.y - inVertex.y;
|
|
|
|
// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.
|
|
var from2toAngle = legFromPtX * legToPtY - legFromPtY * legToPtX;
|
|
var from2otherAngle = legFromPtX * otherPtY - legFromPtY * otherPtX;
|
|
|
|
if ( Math.abs( from2toAngle ) > Number.EPSILON ) {
|
|
|
|
// angle != 180 deg.
|
|
|
|
var other2toAngle = otherPtX * legToPtY - otherPtY * legToPtX;
|
|
// console.log( "from2to: " + from2toAngle + ", from2other: " + from2otherAngle + ", other2to: " + other2toAngle );
|
|
|
|
if ( from2toAngle > 0 ) {
|
|
|
|
// main angle < 180 deg.
|
|
return ( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );
|
|
|
|
} else {
|
|
|
|
// main angle > 180 deg.
|
|
return ( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// angle == 180 deg.
|
|
// console.log( "from2to: 180 deg., from2other: " + from2otherAngle );
|
|
return ( from2otherAngle > 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function removeHoles( contour, holes ) {
|
|
|
|
var shape = contour.concat(); // work on this shape
|
|
var hole;
|
|
|
|
function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {
|
|
|
|
// Check if hole point lies within angle around shape point
|
|
var lastShapeIdx = shape.length - 1;
|
|
|
|
var prevShapeIdx = inShapeIdx - 1;
|
|
if ( prevShapeIdx < 0 ) prevShapeIdx = lastShapeIdx;
|
|
|
|
var nextShapeIdx = inShapeIdx + 1;
|
|
if ( nextShapeIdx > lastShapeIdx ) nextShapeIdx = 0;
|
|
|
|
var insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );
|
|
if ( ! insideAngle ) {
|
|
|
|
// console.log( "Vertex (Shape): " + inShapeIdx + ", Point: " + hole[inHoleIdx].x + "/" + hole[inHoleIdx].y );
|
|
return false;
|
|
|
|
}
|
|
|
|
// Check if shape point lies within angle around hole point
|
|
var lastHoleIdx = hole.length - 1;
|
|
|
|
var prevHoleIdx = inHoleIdx - 1;
|
|
if ( prevHoleIdx < 0 ) prevHoleIdx = lastHoleIdx;
|
|
|
|
var nextHoleIdx = inHoleIdx + 1;
|
|
if ( nextHoleIdx > lastHoleIdx ) nextHoleIdx = 0;
|
|
|
|
insideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );
|
|
if ( ! insideAngle ) {
|
|
|
|
// console.log( "Vertex (Hole): " + inHoleIdx + ", Point: " + shape[inShapeIdx].x + "/" + shape[inShapeIdx].y );
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
function intersectsShapeEdge( inShapePt, inHolePt ) {
|
|
|
|
// checks for intersections with shape edges
|
|
var sIdx, nextIdx, intersection;
|
|
for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {
|
|
|
|
nextIdx = sIdx + 1; nextIdx %= shape.length;
|
|
intersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );
|
|
if ( intersection.length > 0 ) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
var indepHoles = [];
|
|
|
|
function intersectsHoleEdge( inShapePt, inHolePt ) {
|
|
|
|
// checks for intersections with hole edges
|
|
var ihIdx, chkHole,
|
|
hIdx, nextIdx, intersection;
|
|
for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {
|
|
|
|
chkHole = holes[ indepHoles[ ihIdx ]];
|
|
for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {
|
|
|
|
nextIdx = hIdx + 1; nextIdx %= chkHole.length;
|
|
intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );
|
|
if ( intersection.length > 0 ) return true;
|
|
|
|
}
|
|
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
var holeIndex, shapeIndex,
|
|
shapePt, holePt,
|
|
holeIdx, cutKey, failedCuts = [],
|
|
tmpShape1, tmpShape2,
|
|
tmpHole1, tmpHole2;
|
|
|
|
for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
indepHoles.push( h );
|
|
|
|
}
|
|
|
|
var minShapeIndex = 0;
|
|
var counter = indepHoles.length * 2;
|
|
while ( indepHoles.length > 0 ) {
|
|
|
|
counter --;
|
|
if ( counter < 0 ) {
|
|
|
|
console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" );
|
|
break;
|
|
|
|
}
|
|
|
|
// search for shape-vertex and hole-vertex,
|
|
// which can be connected without intersections
|
|
for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {
|
|
|
|
shapePt = shape[ shapeIndex ];
|
|
holeIndex = - 1;
|
|
|
|
// search for hole which can be reached without intersections
|
|
for ( var h = 0; h < indepHoles.length; h ++ ) {
|
|
|
|
holeIdx = indepHoles[ h ];
|
|
|
|
// prevent multiple checks
|
|
cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx;
|
|
if ( failedCuts[ cutKey ] !== undefined ) continue;
|
|
|
|
hole = holes[ holeIdx ];
|
|
for ( var h2 = 0; h2 < hole.length; h2 ++ ) {
|
|
|
|
holePt = hole[ h2 ];
|
|
if ( ! isCutLineInsideAngles( shapeIndex, h2 ) ) continue;
|
|
if ( intersectsShapeEdge( shapePt, holePt ) ) continue;
|
|
if ( intersectsHoleEdge( shapePt, holePt ) ) continue;
|
|
|
|
holeIndex = h2;
|
|
indepHoles.splice( h, 1 );
|
|
|
|
tmpShape1 = shape.slice( 0, shapeIndex + 1 );
|
|
tmpShape2 = shape.slice( shapeIndex );
|
|
tmpHole1 = hole.slice( holeIndex );
|
|
tmpHole2 = hole.slice( 0, holeIndex + 1 );
|
|
|
|
shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
|
|
|
|
minShapeIndex = shapeIndex;
|
|
|
|
// Debug only, to show the selected cuts
|
|
// glob_CutLines.push( [ shapePt, holePt ] );
|
|
|
|
break;
|
|
|
|
}
|
|
if ( holeIndex >= 0 ) break; // hole-vertex found
|
|
|
|
failedCuts[ cutKey ] = true; // remember failure
|
|
|
|
}
|
|
if ( holeIndex >= 0 ) break; // hole-vertex found
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return shape; /* shape with no holes */
|
|
|
|
}
|
|
|
|
|
|
var i, il, f, face,
|
|
key, index,
|
|
allPointsMap = {};
|
|
|
|
// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
|
|
|
|
var allpoints = contour.concat();
|
|
|
|
for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
Array.prototype.push.apply( allpoints, holes[ h ] );
|
|
|
|
}
|
|
|
|
//console.log( "allpoints",allpoints, allpoints.length );
|
|
|
|
// prepare all points map
|
|
|
|
for ( i = 0, il = allpoints.length; i < il; i ++ ) {
|
|
|
|
key = allpoints[ i ].x + ":" + allpoints[ i ].y;
|
|
|
|
if ( allPointsMap[ key ] !== undefined ) {
|
|
|
|
console.warn( "THREE.ShapeUtils: Duplicate point", key, i );
|
|
|
|
}
|
|
|
|
allPointsMap[ key ] = i;
|
|
|
|
}
|
|
|
|
// remove holes by cutting paths to holes and adding them to the shape
|
|
var shapeWithoutHoles = removeHoles( contour, holes );
|
|
|
|
var triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape
|
|
//console.log( "triangles",triangles, triangles.length );
|
|
|
|
// check all face vertices against all points map
|
|
|
|
for ( i = 0, il = triangles.length; i < il; i ++ ) {
|
|
|
|
face = triangles[ i ];
|
|
|
|
for ( f = 0; f < 3; f ++ ) {
|
|
|
|
key = face[ f ].x + ":" + face[ f ].y;
|
|
|
|
index = allPointsMap[ key ];
|
|
|
|
if ( index !== undefined ) {
|
|
|
|
face[ f ] = index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return triangles.concat();
|
|
|
|
},
|
|
|
|
isClockWise: function ( pts ) {
|
|
|
|
return ShapeUtils.area( pts ) < 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
*
|
|
* Creates extruded geometry from a path shape.
|
|
*
|
|
* parameters = {
|
|
*
|
|
* curveSegments: <int>, // number of points on the curves
|
|
* steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
|
|
* amount: <int>, // Depth to extrude the shape
|
|
*
|
|
* bevelEnabled: <bool>, // turn on bevel
|
|
* bevelThickness: <float>, // how deep into the original shape bevel goes
|
|
* bevelSize: <float>, // how far from shape outline is bevel
|
|
* bevelSegments: <int>, // number of bevel layers
|
|
*
|
|
* extrudePath: <THREE.Curve> // curve to extrude shape along
|
|
* frames: <Object> // containing arrays of tangents, normals, binormals
|
|
*
|
|
* UVGenerator: <Object> // object that provides UV generator functions
|
|
*
|
|
* }
|
|
*/
|
|
|
|
// ExtrudeGeometry
|
|
|
|
function ExtrudeGeometry( shapes, options ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'ExtrudeGeometry';
|
|
|
|
this.parameters = {
|
|
shapes: shapes,
|
|
options: options
|
|
};
|
|
|
|
this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
|
|
ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
|
|
|
|
// ExtrudeBufferGeometry
|
|
|
|
function ExtrudeBufferGeometry( shapes, options ) {
|
|
|
|
if ( typeof ( shapes ) === "undefined" ) {
|
|
|
|
shapes = [];
|
|
return;
|
|
|
|
}
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'ExtrudeBufferGeometry';
|
|
|
|
shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
|
|
|
|
this.addShapeList( shapes, options );
|
|
|
|
this.computeVertexNormals();
|
|
|
|
// can't really use automatic vertex normals
|
|
// as then front and back sides get smoothed too
|
|
// should do separate smoothing just for sides
|
|
|
|
//this.computeVertexNormals();
|
|
|
|
//console.log( "took", ( Date.now() - startTime ) );
|
|
|
|
}
|
|
|
|
ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
|
|
|
|
ExtrudeBufferGeometry.prototype.getArrays = function () {
|
|
|
|
var positionAttribute = this.getAttribute( "position" );
|
|
var verticesArray = positionAttribute ? Array.prototype.slice.call( positionAttribute.array ) : [];
|
|
|
|
var uvAttribute = this.getAttribute( "uv" );
|
|
var uvArray = uvAttribute ? Array.prototype.slice.call( uvAttribute.array ) : [];
|
|
|
|
var IndexAttribute = this.index;
|
|
var indicesArray = IndexAttribute ? Array.prototype.slice.call( IndexAttribute.array ) : [];
|
|
|
|
return {
|
|
position: verticesArray,
|
|
uv: uvArray,
|
|
index: indicesArray
|
|
};
|
|
|
|
};
|
|
|
|
ExtrudeBufferGeometry.prototype.addShapeList = function ( shapes, options ) {
|
|
|
|
var sl = shapes.length;
|
|
options.arrays = this.getArrays();
|
|
|
|
for ( var s = 0; s < sl; s ++ ) {
|
|
|
|
var shape = shapes[ s ];
|
|
this.addShape( shape, options );
|
|
|
|
}
|
|
|
|
this.setIndex( options.arrays.index );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( options.arrays.position, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( options.arrays.uv, 2 ) );
|
|
|
|
};
|
|
|
|
ExtrudeBufferGeometry.prototype.addShape = function ( shape, options ) {
|
|
|
|
var arrays = options.arrays ? options.arrays : this.getArrays();
|
|
var verticesArray = arrays.position;
|
|
var indicesArray = arrays.index;
|
|
var uvArray = arrays.uv;
|
|
|
|
var placeholder = [];
|
|
|
|
|
|
var amount = options.amount !== undefined ? options.amount : 100;
|
|
|
|
var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
|
|
var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
|
|
var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
|
|
|
|
var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
|
|
|
|
var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
|
|
|
|
var steps = options.steps !== undefined ? options.steps : 1;
|
|
|
|
var extrudePath = options.extrudePath;
|
|
var extrudePts, extrudeByPath = false;
|
|
|
|
// Use default WorldUVGenerator if no UV generators are specified.
|
|
var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;
|
|
|
|
var splineTube, binormal, normal, position2;
|
|
if ( extrudePath ) {
|
|
|
|
extrudePts = extrudePath.getSpacedPoints( steps );
|
|
|
|
extrudeByPath = true;
|
|
bevelEnabled = false; // bevels not supported for path extrusion
|
|
|
|
// SETUP TNB variables
|
|
|
|
// TODO1 - have a .isClosed in spline?
|
|
|
|
splineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );
|
|
|
|
// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
|
|
|
|
binormal = new Vector3();
|
|
normal = new Vector3();
|
|
position2 = new Vector3();
|
|
|
|
}
|
|
|
|
// Safeguards if bevels are not enabled
|
|
|
|
if ( ! bevelEnabled ) {
|
|
|
|
bevelSegments = 0;
|
|
bevelThickness = 0;
|
|
bevelSize = 0;
|
|
|
|
}
|
|
|
|
// Variables initialization
|
|
|
|
var ahole, h, hl; // looping of holes
|
|
var scope = this;
|
|
|
|
var shapePoints = shape.extractPoints( curveSegments );
|
|
|
|
var vertices = shapePoints.shape;
|
|
var holes = shapePoints.holes;
|
|
|
|
var reverse = ! ShapeUtils.isClockWise( vertices );
|
|
|
|
if ( reverse ) {
|
|
|
|
vertices = vertices.reverse();
|
|
|
|
// Maybe we should also check if holes are in the opposite direction, just to be safe ...
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
|
|
if ( ShapeUtils.isClockWise( ahole ) ) {
|
|
|
|
holes[ h ] = ahole.reverse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!
|
|
|
|
}
|
|
|
|
|
|
var faces = ShapeUtils.triangulateShape( vertices, holes );
|
|
|
|
/* Vertices */
|
|
|
|
var contour = vertices; // vertices has all points but contour has only points of circumference
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
|
|
vertices = vertices.concat( ahole );
|
|
|
|
}
|
|
|
|
|
|
function scalePt2( pt, vec, size ) {
|
|
|
|
if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
|
|
|
|
return vec.clone().multiplyScalar( size ).add( pt );
|
|
|
|
}
|
|
|
|
var b, bs, t, z,
|
|
vert, vlen = vertices.length,
|
|
face, flen = faces.length;
|
|
|
|
|
|
// Find directions for point movement
|
|
|
|
|
|
function getBevelVec( inPt, inPrev, inNext ) {
|
|
|
|
// computes for inPt the corresponding point inPt' on a new contour
|
|
// shifted by 1 unit (length of normalized vector) to the left
|
|
// if we walk along contour clockwise, this new contour is outside the old one
|
|
//
|
|
// inPt' is the intersection of the two lines parallel to the two
|
|
// adjacent edges of inPt at a distance of 1 unit on the left side.
|
|
|
|
var v_trans_x, v_trans_y, shrink_by = 1; // resulting translation vector for inPt
|
|
|
|
// good reading for geometry algorithms (here: line-line intersection)
|
|
// http://geomalgorithms.com/a05-_intersect-1.html
|
|
|
|
var v_prev_x = inPt.x - inPrev.x,
|
|
v_prev_y = inPt.y - inPrev.y;
|
|
var v_next_x = inNext.x - inPt.x,
|
|
v_next_y = inNext.y - inPt.y;
|
|
|
|
var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
|
|
|
|
// check for collinear edges
|
|
var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
|
|
|
|
if ( Math.abs( collinear0 ) > Number.EPSILON ) {
|
|
|
|
// not collinear
|
|
|
|
// length of vectors for normalizing
|
|
|
|
var v_prev_len = Math.sqrt( v_prev_lensq );
|
|
var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
|
|
|
|
// shift adjacent points by unit vectors to the left
|
|
|
|
var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
|
|
var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
|
|
|
|
var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
|
|
var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
|
|
|
|
// scaling factor for v_prev to intersection point
|
|
|
|
var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
|
|
( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
|
|
( v_prev_x * v_next_y - v_prev_y * v_next_x );
|
|
|
|
// vector from inPt to intersection point
|
|
|
|
v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
|
|
v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
|
|
|
|
// Don't normalize!, otherwise sharp corners become ugly
|
|
// but prevent crazy spikes
|
|
var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
|
|
if ( v_trans_lensq <= 2 ) {
|
|
|
|
return new Vector2( v_trans_x, v_trans_y );
|
|
|
|
} else {
|
|
|
|
shrink_by = Math.sqrt( v_trans_lensq / 2 );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// handle special case of collinear edges
|
|
|
|
var direction_eq = false; // assumes: opposite
|
|
if ( v_prev_x > Number.EPSILON ) {
|
|
|
|
if ( v_next_x > Number.EPSILON ) {
|
|
|
|
direction_eq = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( v_prev_x < - Number.EPSILON ) {
|
|
|
|
if ( v_next_x < - Number.EPSILON ) {
|
|
|
|
direction_eq = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
|
|
|
|
direction_eq = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( direction_eq ) {
|
|
|
|
// console.log("Warning: lines are a straight sequence");
|
|
v_trans_x = - v_prev_y;
|
|
v_trans_y = v_prev_x;
|
|
shrink_by = Math.sqrt( v_prev_lensq );
|
|
|
|
} else {
|
|
|
|
// console.log("Warning: lines are a straight spike");
|
|
v_trans_x = v_prev_x;
|
|
v_trans_y = v_prev_y;
|
|
shrink_by = Math.sqrt( v_prev_lensq / 2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
|
|
|
|
}
|
|
|
|
|
|
var contourMovements = [];
|
|
|
|
for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
|
|
|
|
if ( j === il ) j = 0;
|
|
if ( k === il ) k = 0;
|
|
|
|
// (j)---(i)---(k)
|
|
// console.log('i,j,k', i, j , k)
|
|
|
|
contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
|
|
|
|
}
|
|
|
|
var holesMovements = [],
|
|
oneHoleMovements, verticesMovements = contourMovements.concat();
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
|
|
oneHoleMovements = [];
|
|
|
|
for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
|
|
|
|
if ( j === il ) j = 0;
|
|
if ( k === il ) k = 0;
|
|
|
|
// (j)---(i)---(k)
|
|
oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
|
|
|
|
}
|
|
|
|
holesMovements.push( oneHoleMovements );
|
|
verticesMovements = verticesMovements.concat( oneHoleMovements );
|
|
|
|
}
|
|
|
|
|
|
// Loop bevelSegments, 1 for the front, 1 for the back
|
|
|
|
for ( b = 0; b < bevelSegments; b ++ ) {
|
|
|
|
//for ( b = bevelSegments; b > 0; b -- ) {
|
|
|
|
t = b / bevelSegments;
|
|
z = bevelThickness * Math.cos( t * Math.PI / 2 );
|
|
bs = bevelSize * Math.sin( t * Math.PI / 2 );
|
|
|
|
// contract shape
|
|
|
|
for ( i = 0, il = contour.length; i < il; i ++ ) {
|
|
|
|
vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
|
|
|
|
v( vert.x, vert.y, - z );
|
|
|
|
}
|
|
|
|
// expand holes
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
oneHoleMovements = holesMovements[ h ];
|
|
|
|
for ( i = 0, il = ahole.length; i < il; i ++ ) {
|
|
|
|
vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
|
|
|
|
v( vert.x, vert.y, - z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bs = bevelSize;
|
|
|
|
// Back facing vertices
|
|
|
|
for ( i = 0; i < vlen; i ++ ) {
|
|
|
|
vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
|
|
|
|
if ( ! extrudeByPath ) {
|
|
|
|
v( vert.x, vert.y, 0 );
|
|
|
|
} else {
|
|
|
|
// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
|
|
|
|
normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
|
|
binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
|
|
|
|
position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
|
|
|
|
v( position2.x, position2.y, position2.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Add stepped vertices...
|
|
// Including front facing vertices
|
|
|
|
var s;
|
|
|
|
for ( s = 1; s <= steps; s ++ ) {
|
|
|
|
for ( i = 0; i < vlen; i ++ ) {
|
|
|
|
vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
|
|
|
|
if ( ! extrudeByPath ) {
|
|
|
|
v( vert.x, vert.y, amount / steps * s );
|
|
|
|
} else {
|
|
|
|
// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
|
|
|
|
normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
|
|
binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
|
|
|
|
position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
|
|
|
|
v( position2.x, position2.y, position2.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Add bevel segments planes
|
|
|
|
//for ( b = 1; b <= bevelSegments; b ++ ) {
|
|
for ( b = bevelSegments - 1; b >= 0; b -- ) {
|
|
|
|
t = b / bevelSegments;
|
|
z = bevelThickness * Math.cos( t * Math.PI / 2 );
|
|
bs = bevelSize * Math.sin( t * Math.PI / 2 );
|
|
|
|
// contract shape
|
|
|
|
for ( i = 0, il = contour.length; i < il; i ++ ) {
|
|
|
|
vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
|
|
v( vert.x, vert.y, amount + z );
|
|
|
|
}
|
|
|
|
// expand holes
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
oneHoleMovements = holesMovements[ h ];
|
|
|
|
for ( i = 0, il = ahole.length; i < il; i ++ ) {
|
|
|
|
vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
|
|
|
|
if ( ! extrudeByPath ) {
|
|
|
|
v( vert.x, vert.y, amount + z );
|
|
|
|
} else {
|
|
|
|
v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Faces */
|
|
|
|
// Top and bottom faces
|
|
|
|
buildLidFaces();
|
|
|
|
// Sides faces
|
|
|
|
buildSideFaces();
|
|
|
|
|
|
///// Internal functions
|
|
|
|
function buildLidFaces() {
|
|
|
|
var start = verticesArray.length/3;
|
|
|
|
if ( bevelEnabled ) {
|
|
|
|
var layer = 0; // steps + 1
|
|
var offset = vlen * layer;
|
|
|
|
// Bottom faces
|
|
|
|
for ( i = 0; i < flen; i ++ ) {
|
|
|
|
face = faces[ i ];
|
|
f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
|
|
|
|
}
|
|
|
|
layer = steps + bevelSegments * 2;
|
|
offset = vlen * layer;
|
|
|
|
// Top faces
|
|
|
|
for ( i = 0; i < flen; i ++ ) {
|
|
|
|
face = faces[ i ];
|
|
f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Bottom faces
|
|
|
|
for ( i = 0; i < flen; i ++ ) {
|
|
|
|
face = faces[ i ];
|
|
f3( face[ 2 ], face[ 1 ], face[ 0 ] );
|
|
|
|
}
|
|
|
|
// Top faces
|
|
|
|
for ( i = 0; i < flen; i ++ ) {
|
|
|
|
face = faces[ i ];
|
|
f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
scope.addGroup( start, verticesArray.length/3 -start, options.material !== undefined ? options.material : 0);
|
|
|
|
}
|
|
|
|
// Create faces for the z-sides of the shape
|
|
|
|
function buildSideFaces() {
|
|
|
|
var start = verticesArray.length/3;
|
|
var layeroffset = 0;
|
|
sidewalls( contour, layeroffset );
|
|
layeroffset += contour.length;
|
|
|
|
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
|
|
|
|
ahole = holes[ h ];
|
|
sidewalls( ahole, layeroffset );
|
|
|
|
//, true
|
|
layeroffset += ahole.length;
|
|
|
|
}
|
|
|
|
|
|
scope.addGroup( start, verticesArray.length/3 -start, options.extrudeMaterial !== undefined ? options.extrudeMaterial : 1);
|
|
|
|
|
|
}
|
|
|
|
function sidewalls( contour, layeroffset ) {
|
|
|
|
var j, k;
|
|
i = contour.length;
|
|
|
|
while ( -- i >= 0 ) {
|
|
|
|
j = i;
|
|
k = i - 1;
|
|
if ( k < 0 ) k = contour.length - 1;
|
|
|
|
//console.log('b', i,j, i-1, k,vertices.length);
|
|
|
|
var s = 0,
|
|
sl = steps + bevelSegments * 2;
|
|
|
|
for ( s = 0; s < sl; s ++ ) {
|
|
|
|
var slen1 = vlen * s;
|
|
var slen2 = vlen * ( s + 1 );
|
|
|
|
var a = layeroffset + j + slen1,
|
|
b = layeroffset + k + slen1,
|
|
c = layeroffset + k + slen2,
|
|
d = layeroffset + j + slen2;
|
|
|
|
f4( a, b, c, d, contour, s, sl, j, k );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function v( x, y, z ) {
|
|
|
|
placeholder.push( x );
|
|
placeholder.push( y );
|
|
placeholder.push( z );
|
|
|
|
}
|
|
|
|
|
|
function f3( a, b, c ) {
|
|
|
|
addVertex( a );
|
|
addVertex( b );
|
|
addVertex( c );
|
|
|
|
var nextIndex = verticesArray.length / 3;
|
|
var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
|
|
|
|
addUV( uvs[ 0 ] );
|
|
addUV( uvs[ 1 ] );
|
|
addUV( uvs[ 2 ] );
|
|
|
|
}
|
|
|
|
function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {
|
|
|
|
addVertex( a );
|
|
addVertex( b );
|
|
addVertex( d );
|
|
|
|
addVertex( b );
|
|
addVertex( c );
|
|
addVertex( d );
|
|
|
|
|
|
var nextIndex = verticesArray.length / 3;
|
|
var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
|
|
|
|
addUV( uvs[ 0 ] );
|
|
addUV( uvs[ 1 ] );
|
|
addUV( uvs[ 3 ] );
|
|
|
|
addUV( uvs[ 1 ] );
|
|
addUV( uvs[ 2 ] );
|
|
addUV( uvs[ 3 ] );
|
|
|
|
}
|
|
|
|
function addVertex( index ) {
|
|
|
|
indicesArray.push( verticesArray.length / 3 );
|
|
verticesArray.push( placeholder[ index * 3 + 0 ] );
|
|
verticesArray.push( placeholder[ index * 3 + 1 ] );
|
|
verticesArray.push( placeholder[ index * 3 + 2 ] );
|
|
|
|
}
|
|
|
|
|
|
function addUV( vector2 ) {
|
|
|
|
uvArray.push( vector2.x );
|
|
uvArray.push( vector2.y );
|
|
|
|
}
|
|
|
|
if ( ! options.arrays ) {
|
|
|
|
this.setIndex( indicesArray );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( options.arrays.uv, 2 ) );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
ExtrudeGeometry.WorldUVGenerator = {
|
|
|
|
generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
|
|
|
|
var a_x = vertices[ indexA * 3 ];
|
|
var a_y = vertices[ indexA * 3 + 1 ];
|
|
var b_x = vertices[ indexB * 3 ];
|
|
var b_y = vertices[ indexB * 3 + 1 ];
|
|
var c_x = vertices[ indexC * 3 ];
|
|
var c_y = vertices[ indexC * 3 + 1 ];
|
|
|
|
return [
|
|
new Vector2( a_x, a_y ),
|
|
new Vector2( b_x, b_y ),
|
|
new Vector2( c_x, c_y )
|
|
];
|
|
|
|
},
|
|
|
|
generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
|
|
|
|
var a_x = vertices[ indexA * 3 ];
|
|
var a_y = vertices[ indexA * 3 + 1 ];
|
|
var a_z = vertices[ indexA * 3 + 2 ];
|
|
var b_x = vertices[ indexB * 3 ];
|
|
var b_y = vertices[ indexB * 3 + 1 ];
|
|
var b_z = vertices[ indexB * 3 + 2 ];
|
|
var c_x = vertices[ indexC * 3 ];
|
|
var c_y = vertices[ indexC * 3 + 1 ];
|
|
var c_z = vertices[ indexC * 3 + 2 ];
|
|
var d_x = vertices[ indexD * 3 ];
|
|
var d_y = vertices[ indexD * 3 + 1 ];
|
|
var d_z = vertices[ indexD * 3 + 2 ];
|
|
|
|
if ( Math.abs( a_y - b_y ) < 0.01 ) {
|
|
|
|
return [
|
|
new Vector2( a_x, 1 - a_z ),
|
|
new Vector2( b_x, 1 - b_z ),
|
|
new Vector2( c_x, 1 - c_z ),
|
|
new Vector2( d_x, 1 - d_z )
|
|
];
|
|
|
|
} else {
|
|
|
|
return [
|
|
new Vector2( a_y, 1 - a_z ),
|
|
new Vector2( b_y, 1 - b_z ),
|
|
new Vector2( c_y, 1 - c_z ),
|
|
new Vector2( d_y, 1 - d_z )
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* Text = 3D Text
|
|
*
|
|
* parameters = {
|
|
* font: <THREE.Font>, // font
|
|
*
|
|
* size: <float>, // size of the text
|
|
* height: <float>, // thickness to extrude text
|
|
* curveSegments: <int>, // number of points on the curves
|
|
*
|
|
* bevelEnabled: <bool>, // turn on bevel
|
|
* bevelThickness: <float>, // how deep into text bevel goes
|
|
* bevelSize: <float> // how far from text outline is bevel
|
|
* }
|
|
*/
|
|
|
|
// TextGeometry
|
|
|
|
function TextGeometry( text, parameters ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'TextGeometry';
|
|
|
|
this.parameters = {
|
|
text: text,
|
|
parameters: parameters
|
|
};
|
|
|
|
this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
TextGeometry.prototype = Object.create( Geometry.prototype );
|
|
TextGeometry.prototype.constructor = TextGeometry;
|
|
|
|
// TextBufferGeometry
|
|
|
|
function TextBufferGeometry( text, parameters ) {
|
|
|
|
parameters = parameters || {};
|
|
|
|
var font = parameters.font;
|
|
|
|
if ( ( font && font.isFont ) === false ) {
|
|
|
|
console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
|
|
return new Geometry();
|
|
|
|
}
|
|
|
|
var shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );
|
|
|
|
// translate parameters to ExtrudeGeometry API
|
|
|
|
parameters.amount = parameters.height !== undefined ? parameters.height : 50;
|
|
|
|
// defaults
|
|
|
|
if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
|
|
if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
|
|
if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
|
|
|
|
ExtrudeBufferGeometry.call( this, shapes, parameters );
|
|
|
|
this.type = 'TextBufferGeometry';
|
|
|
|
}
|
|
|
|
TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype );
|
|
TextBufferGeometry.prototype.constructor = TextBufferGeometry;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// SphereGeometry
|
|
|
|
function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'SphereGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments,
|
|
phiStart: phiStart,
|
|
phiLength: phiLength,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
SphereGeometry.prototype = Object.create( Geometry.prototype );
|
|
SphereGeometry.prototype.constructor = SphereGeometry;
|
|
|
|
// SphereBufferGeometry
|
|
|
|
function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'SphereBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
widthSegments: widthSegments,
|
|
heightSegments: heightSegments,
|
|
phiStart: phiStart,
|
|
phiLength: phiLength,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
radius = radius || 50;
|
|
|
|
widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
|
|
heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
|
|
|
|
phiStart = phiStart !== undefined ? phiStart : 0;
|
|
phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
|
|
|
|
thetaStart = thetaStart !== undefined ? thetaStart : 0;
|
|
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
|
|
|
|
var thetaEnd = thetaStart + thetaLength;
|
|
|
|
var ix, iy;
|
|
|
|
var index = 0;
|
|
var grid = [];
|
|
|
|
var vertex = new Vector3();
|
|
var normal = new Vector3();
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( iy = 0; iy <= heightSegments; iy ++ ) {
|
|
|
|
var verticesRow = [];
|
|
|
|
var v = iy / heightSegments;
|
|
|
|
for ( ix = 0; ix <= widthSegments; ix ++ ) {
|
|
|
|
var u = ix / widthSegments;
|
|
|
|
// vertex
|
|
|
|
vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
|
|
vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
|
|
vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
normal.set( vertex.x, vertex.y, vertex.z ).normalize();
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// uv
|
|
|
|
uvs.push( u, 1 - v );
|
|
|
|
verticesRow.push( index ++ );
|
|
|
|
}
|
|
|
|
grid.push( verticesRow );
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
for ( iy = 0; iy < heightSegments; iy ++ ) {
|
|
|
|
for ( ix = 0; ix < widthSegments; ix ++ ) {
|
|
|
|
var a = grid[ iy ][ ix + 1 ];
|
|
var b = grid[ iy ][ ix ];
|
|
var c = grid[ iy + 1 ][ ix ];
|
|
var d = grid[ iy + 1 ][ ix + 1 ];
|
|
|
|
if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );
|
|
if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
|
|
|
|
/**
|
|
* @author Kaleb Murphy
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// RingGeometry
|
|
|
|
function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'RingGeometry';
|
|
|
|
this.parameters = {
|
|
innerRadius: innerRadius,
|
|
outerRadius: outerRadius,
|
|
thetaSegments: thetaSegments,
|
|
phiSegments: phiSegments,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
RingGeometry.prototype = Object.create( Geometry.prototype );
|
|
RingGeometry.prototype.constructor = RingGeometry;
|
|
|
|
// RingBufferGeometry
|
|
|
|
function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'RingBufferGeometry';
|
|
|
|
this.parameters = {
|
|
innerRadius: innerRadius,
|
|
outerRadius: outerRadius,
|
|
thetaSegments: thetaSegments,
|
|
phiSegments: phiSegments,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
innerRadius = innerRadius || 20;
|
|
outerRadius = outerRadius || 50;
|
|
|
|
thetaStart = thetaStart !== undefined ? thetaStart : 0;
|
|
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
|
|
|
|
thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
|
|
phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// some helper variables
|
|
|
|
var segment;
|
|
var radius = innerRadius;
|
|
var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
|
|
var vertex = new Vector3();
|
|
var uv = new Vector2();
|
|
var j, i;
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( j = 0; j <= phiSegments; j ++ ) {
|
|
|
|
for ( i = 0; i <= thetaSegments; i ++ ) {
|
|
|
|
// values are generate from the inside of the ring to the outside
|
|
|
|
segment = thetaStart + i / thetaSegments * thetaLength;
|
|
|
|
// vertex
|
|
|
|
vertex.x = radius * Math.cos( segment );
|
|
vertex.y = radius * Math.sin( segment );
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
normals.push( 0, 0, 1 );
|
|
|
|
// uv
|
|
|
|
uv.x = ( vertex.x / outerRadius + 1 ) / 2;
|
|
uv.y = ( vertex.y / outerRadius + 1 ) / 2;
|
|
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
}
|
|
|
|
// increase the radius for next row of vertices
|
|
|
|
radius += radiusStep;
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
for ( j = 0; j < phiSegments; j ++ ) {
|
|
|
|
var thetaSegmentLevel = j * ( thetaSegments + 1 );
|
|
|
|
for ( i = 0; i < thetaSegments; i ++ ) {
|
|
|
|
segment = i + thetaSegmentLevel;
|
|
|
|
var a = segment;
|
|
var b = segment + thetaSegments + 1;
|
|
var c = segment + thetaSegments + 2;
|
|
var d = segment + 1;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
RingBufferGeometry.prototype.constructor = RingBufferGeometry;
|
|
|
|
/**
|
|
* @author astrodud / http://astrodud.isgreat.org/
|
|
* @author zz85 / https://github.com/zz85
|
|
* @author bhouston / http://clara.io
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// LatheGeometry
|
|
|
|
function LatheGeometry( points, segments, phiStart, phiLength ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'LatheGeometry';
|
|
|
|
this.parameters = {
|
|
points: points,
|
|
segments: segments,
|
|
phiStart: phiStart,
|
|
phiLength: phiLength
|
|
};
|
|
|
|
this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
LatheGeometry.prototype = Object.create( Geometry.prototype );
|
|
LatheGeometry.prototype.constructor = LatheGeometry;
|
|
|
|
// LatheBufferGeometry
|
|
|
|
function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'LatheBufferGeometry';
|
|
|
|
this.parameters = {
|
|
points: points,
|
|
segments: segments,
|
|
phiStart: phiStart,
|
|
phiLength: phiLength
|
|
};
|
|
|
|
segments = Math.floor( segments ) || 12;
|
|
phiStart = phiStart || 0;
|
|
phiLength = phiLength || Math.PI * 2;
|
|
|
|
// clamp phiLength so it's in range of [ 0, 2PI ]
|
|
|
|
phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );
|
|
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var base;
|
|
var inverseSegments = 1.0 / segments;
|
|
var vertex = new Vector3();
|
|
var uv = new Vector2();
|
|
var i, j;
|
|
|
|
// generate vertices and uvs
|
|
|
|
for ( i = 0; i <= segments; i ++ ) {
|
|
|
|
var phi = phiStart + i * inverseSegments * phiLength;
|
|
|
|
var sin = Math.sin( phi );
|
|
var cos = Math.cos( phi );
|
|
|
|
for ( j = 0; j <= ( points.length - 1 ); j ++ ) {
|
|
|
|
// vertex
|
|
|
|
vertex.x = points[ j ].x * sin;
|
|
vertex.y = points[ j ].y;
|
|
vertex.z = points[ j ].x * cos;
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// uv
|
|
|
|
uv.x = i / segments;
|
|
uv.y = j / ( points.length - 1 );
|
|
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
for ( i = 0; i < segments; i ++ ) {
|
|
|
|
for ( j = 0; j < ( points.length - 1 ); j ++ ) {
|
|
|
|
base = j + i * points.length;
|
|
|
|
var a = base;
|
|
var b = base + points.length;
|
|
var c = base + points.length + 1;
|
|
var d = base + 1;
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
// generate normals
|
|
|
|
this.computeVertexNormals();
|
|
|
|
// if the geometry is closed, we need to average the normals along the seam.
|
|
// because the corresponding vertices are identical (but still have different UVs).
|
|
|
|
if ( phiLength === Math.PI * 2 ) {
|
|
|
|
var normals = this.attributes.normal.array;
|
|
var n1 = new Vector3();
|
|
var n2 = new Vector3();
|
|
var n = new Vector3();
|
|
|
|
// this is the buffer offset for the last line of vertices
|
|
|
|
base = segments * points.length * 3;
|
|
|
|
for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {
|
|
|
|
// select the normal of the vertex in the first line
|
|
|
|
n1.x = normals[ j + 0 ];
|
|
n1.y = normals[ j + 1 ];
|
|
n1.z = normals[ j + 2 ];
|
|
|
|
// select the normal of the vertex in the last line
|
|
|
|
n2.x = normals[ base + j + 0 ];
|
|
n2.y = normals[ base + j + 1 ];
|
|
n2.z = normals[ base + j + 2 ];
|
|
|
|
// average normals
|
|
|
|
n.addVectors( n1, n2 ).normalize();
|
|
|
|
// assign the new values to both normals
|
|
|
|
normals[ j + 0 ] = normals[ base + j + 0 ] = n.x;
|
|
normals[ j + 1 ] = normals[ base + j + 1 ] = n.y;
|
|
normals[ j + 2 ] = normals[ base + j + 2 ] = n.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
LatheBufferGeometry.prototype.constructor = LatheBufferGeometry;
|
|
|
|
/**
|
|
* @author jonobr1 / http://jonobr1.com
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// ShapeGeometry
|
|
|
|
function ShapeGeometry( shapes, curveSegments ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'ShapeGeometry';
|
|
|
|
if ( typeof curveSegments === 'object' ) {
|
|
|
|
console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
|
|
|
|
curveSegments = curveSegments.curveSegments;
|
|
|
|
}
|
|
|
|
this.parameters = {
|
|
shapes: shapes,
|
|
curveSegments: curveSegments
|
|
};
|
|
|
|
this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
ShapeGeometry.prototype = Object.create( Geometry.prototype );
|
|
ShapeGeometry.prototype.constructor = ShapeGeometry;
|
|
|
|
// ShapeBufferGeometry
|
|
|
|
function ShapeBufferGeometry( shapes, curveSegments ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'ShapeBufferGeometry';
|
|
|
|
this.parameters = {
|
|
shapes: shapes,
|
|
curveSegments: curveSegments
|
|
};
|
|
|
|
curveSegments = curveSegments || 12;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var groupStart = 0;
|
|
var groupCount = 0;
|
|
|
|
// allow single and array values for "shapes" parameter
|
|
|
|
if ( Array.isArray( shapes ) === false ) {
|
|
|
|
addShape( shapes );
|
|
|
|
} else {
|
|
|
|
for ( var i = 0; i < shapes.length; i ++ ) {
|
|
|
|
addShape( shapes[ i ] );
|
|
|
|
this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
|
|
|
|
groupStart += groupCount;
|
|
groupCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
|
|
// helper functions
|
|
|
|
function addShape( shape ) {
|
|
|
|
var i, l, shapeHole;
|
|
|
|
var indexOffset = vertices.length / 3;
|
|
var points = shape.extractPoints( curveSegments );
|
|
|
|
var shapeVertices = points.shape;
|
|
var shapeHoles = points.holes;
|
|
|
|
// check direction of vertices
|
|
|
|
if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
|
|
|
|
shapeVertices = shapeVertices.reverse();
|
|
|
|
// also check if holes are in the opposite direction
|
|
|
|
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
|
|
|
shapeHole = shapeHoles[ i ];
|
|
|
|
if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
|
|
|
|
shapeHoles[ i ] = shapeHole.reverse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
|
|
|
|
// join vertices of inner and outer paths to a single array
|
|
|
|
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
|
|
|
shapeHole = shapeHoles[ i ];
|
|
shapeVertices = shapeVertices.concat( shapeHole );
|
|
|
|
}
|
|
|
|
// vertices, normals, uvs
|
|
|
|
for ( i = 0, l = shapeVertices.length; i < l; i ++ ) {
|
|
|
|
var vertex = shapeVertices[ i ];
|
|
|
|
vertices.push( vertex.x, vertex.y, 0 );
|
|
normals.push( 0, 0, 1 );
|
|
uvs.push( vertex.x, vertex.y ); // world uvs
|
|
|
|
}
|
|
|
|
// incides
|
|
|
|
for ( i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
var a = face[ 0 ] + indexOffset;
|
|
var b = face[ 1 ] + indexOffset;
|
|
var c = face[ 2 ] + indexOffset;
|
|
|
|
indices.push( a, b, c );
|
|
groupCount += 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
|
|
|
|
/**
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
function EdgesGeometry( geometry, thresholdAngle ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'EdgesGeometry';
|
|
|
|
this.parameters = {
|
|
thresholdAngle: thresholdAngle
|
|
};
|
|
|
|
thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
|
|
|
|
// buffer
|
|
|
|
var vertices = [];
|
|
|
|
// helper variables
|
|
|
|
var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );
|
|
var edge = [ 0, 0 ], edges = {}, edge1, edge2;
|
|
var key, keys = [ 'a', 'b', 'c' ];
|
|
|
|
// prepare source geometry
|
|
|
|
var geometry2;
|
|
|
|
if ( geometry.isBufferGeometry ) {
|
|
|
|
geometry2 = new Geometry();
|
|
geometry2.fromBufferGeometry( geometry );
|
|
|
|
} else {
|
|
|
|
geometry2 = geometry.clone();
|
|
|
|
}
|
|
|
|
geometry2.mergeVertices();
|
|
geometry2.computeFaceNormals();
|
|
|
|
var sourceVertices = geometry2.vertices;
|
|
var faces = geometry2.faces;
|
|
|
|
// now create a data structure where each entry represents an edge with its adjoining faces
|
|
|
|
for ( var i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
for ( var j = 0; j < 3; j ++ ) {
|
|
|
|
edge1 = face[ keys[ j ] ];
|
|
edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
|
|
edge[ 0 ] = Math.min( edge1, edge2 );
|
|
edge[ 1 ] = Math.max( edge1, edge2 );
|
|
|
|
key = edge[ 0 ] + ',' + edge[ 1 ];
|
|
|
|
if ( edges[ key ] === undefined ) {
|
|
|
|
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };
|
|
|
|
} else {
|
|
|
|
edges[ key ].face2 = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// generate vertices
|
|
|
|
for ( key in edges ) {
|
|
|
|
var e = edges[ key ];
|
|
|
|
// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.
|
|
|
|
if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {
|
|
|
|
var vertex = sourceVertices[ e.index1 ];
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
vertex = sourceVertices[ e.index2 ];
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
|
|
}
|
|
|
|
EdgesGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
EdgesGeometry.prototype.constructor = EdgesGeometry;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
// CylinderGeometry
|
|
|
|
function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'CylinderGeometry';
|
|
|
|
this.parameters = {
|
|
radiusTop: radiusTop,
|
|
radiusBottom: radiusBottom,
|
|
height: height,
|
|
radialSegments: radialSegments,
|
|
heightSegments: heightSegments,
|
|
openEnded: openEnded,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
CylinderGeometry.prototype = Object.create( Geometry.prototype );
|
|
CylinderGeometry.prototype.constructor = CylinderGeometry;
|
|
|
|
// CylinderBufferGeometry
|
|
|
|
function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'CylinderBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radiusTop: radiusTop,
|
|
radiusBottom: radiusBottom,
|
|
height: height,
|
|
radialSegments: radialSegments,
|
|
heightSegments: heightSegments,
|
|
openEnded: openEnded,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
var scope = this;
|
|
|
|
radiusTop = radiusTop !== undefined ? radiusTop : 20;
|
|
radiusBottom = radiusBottom !== undefined ? radiusBottom : 20;
|
|
height = height !== undefined ? height : 100;
|
|
|
|
radialSegments = Math.floor( radialSegments ) || 8;
|
|
heightSegments = Math.floor( heightSegments ) || 1;
|
|
|
|
openEnded = openEnded !== undefined ? openEnded : false;
|
|
thetaStart = thetaStart !== undefined ? thetaStart : 0.0;
|
|
thetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var index = 0;
|
|
var indexArray = [];
|
|
var halfHeight = height / 2;
|
|
var groupStart = 0;
|
|
|
|
// generate geometry
|
|
|
|
generateTorso();
|
|
|
|
if ( openEnded === false ) {
|
|
|
|
if ( radiusTop > 0 ) generateCap( true );
|
|
if ( radiusBottom > 0 ) generateCap( false );
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
function generateTorso() {
|
|
|
|
var x, y;
|
|
var normal = new Vector3();
|
|
var vertex = new Vector3();
|
|
|
|
var groupCount = 0;
|
|
|
|
// this will be used to calculate the normal
|
|
var slope = ( radiusBottom - radiusTop ) / height;
|
|
|
|
// generate vertices, normals and uvs
|
|
|
|
for ( y = 0; y <= heightSegments; y ++ ) {
|
|
|
|
var indexRow = [];
|
|
|
|
var v = y / heightSegments;
|
|
|
|
// calculate the radius of the current row
|
|
|
|
var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
|
|
|
|
for ( x = 0; x <= radialSegments; x ++ ) {
|
|
|
|
var u = x / radialSegments;
|
|
|
|
var theta = u * thetaLength + thetaStart;
|
|
|
|
var sinTheta = Math.sin( theta );
|
|
var cosTheta = Math.cos( theta );
|
|
|
|
// vertex
|
|
|
|
vertex.x = radius * sinTheta;
|
|
vertex.y = - v * height + halfHeight;
|
|
vertex.z = radius * cosTheta;
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
normal.set( sinTheta, slope, cosTheta ).normalize();
|
|
normals.push( normal.x, normal.y, normal.z );
|
|
|
|
// uv
|
|
|
|
uvs.push( u, 1 - v );
|
|
|
|
// save index of vertex in respective row
|
|
|
|
indexRow.push( index ++ );
|
|
|
|
}
|
|
|
|
// now save vertices of the row in our index array
|
|
|
|
indexArray.push( indexRow );
|
|
|
|
}
|
|
|
|
// generate indices
|
|
|
|
for ( x = 0; x < radialSegments; x ++ ) {
|
|
|
|
for ( y = 0; y < heightSegments; y ++ ) {
|
|
|
|
// we use the index array to access the correct indices
|
|
|
|
var a = indexArray[ y ][ x ];
|
|
var b = indexArray[ y + 1 ][ x ];
|
|
var c = indexArray[ y + 1 ][ x + 1 ];
|
|
var d = indexArray[ y ][ x + 1 ];
|
|
|
|
// faces
|
|
|
|
indices.push( a, b, d );
|
|
indices.push( b, c, d );
|
|
|
|
// update group counter
|
|
|
|
groupCount += 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// add a group to the geometry. this will ensure multi material support
|
|
|
|
scope.addGroup( groupStart, groupCount, 0 );
|
|
|
|
// calculate new start value for groups
|
|
|
|
groupStart += groupCount;
|
|
|
|
}
|
|
|
|
function generateCap( top ) {
|
|
|
|
var x, centerIndexStart, centerIndexEnd;
|
|
|
|
var uv = new Vector2();
|
|
var vertex = new Vector3();
|
|
|
|
var groupCount = 0;
|
|
|
|
var radius = ( top === true ) ? radiusTop : radiusBottom;
|
|
var sign = ( top === true ) ? 1 : - 1;
|
|
|
|
// save the index of the first center vertex
|
|
centerIndexStart = index;
|
|
|
|
// first we generate the center vertex data of the cap.
|
|
// because the geometry needs one set of uvs per face,
|
|
// we must generate a center vertex per face/segment
|
|
|
|
for ( x = 1; x <= radialSegments; x ++ ) {
|
|
|
|
// vertex
|
|
|
|
vertices.push( 0, halfHeight * sign, 0 );
|
|
|
|
// normal
|
|
|
|
normals.push( 0, sign, 0 );
|
|
|
|
// uv
|
|
|
|
uvs.push( 0.5, 0.5 );
|
|
|
|
// increase index
|
|
|
|
index ++;
|
|
|
|
}
|
|
|
|
// save the index of the last center vertex
|
|
|
|
centerIndexEnd = index;
|
|
|
|
// now we generate the surrounding vertices, normals and uvs
|
|
|
|
for ( x = 0; x <= radialSegments; x ++ ) {
|
|
|
|
var u = x / radialSegments;
|
|
var theta = u * thetaLength + thetaStart;
|
|
|
|
var cosTheta = Math.cos( theta );
|
|
var sinTheta = Math.sin( theta );
|
|
|
|
// vertex
|
|
|
|
vertex.x = radius * sinTheta;
|
|
vertex.y = halfHeight * sign;
|
|
vertex.z = radius * cosTheta;
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
normals.push( 0, sign, 0 );
|
|
|
|
// uv
|
|
|
|
uv.x = ( cosTheta * 0.5 ) + 0.5;
|
|
uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
// increase index
|
|
|
|
index ++;
|
|
|
|
}
|
|
|
|
// generate indices
|
|
|
|
for ( x = 0; x < radialSegments; x ++ ) {
|
|
|
|
var c = centerIndexStart + x;
|
|
var i = centerIndexEnd + x;
|
|
|
|
if ( top === true ) {
|
|
|
|
// face top
|
|
|
|
indices.push( i, i + 1, c );
|
|
|
|
} else {
|
|
|
|
// face bottom
|
|
|
|
indices.push( i + 1, i, c );
|
|
|
|
}
|
|
|
|
groupCount += 3;
|
|
|
|
}
|
|
|
|
// add a group to the geometry. this will ensure multi material support
|
|
|
|
scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
|
|
|
|
// calculate new start value for groups
|
|
|
|
groupStart += groupCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;
|
|
|
|
/**
|
|
* @author abelnation / http://github.com/abelnation
|
|
*/
|
|
|
|
// ConeGeometry
|
|
|
|
function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
|
|
|
|
CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
|
|
|
|
this.type = 'ConeGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
height: height,
|
|
radialSegments: radialSegments,
|
|
heightSegments: heightSegments,
|
|
openEnded: openEnded,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
}
|
|
|
|
ConeGeometry.prototype = Object.create( CylinderGeometry.prototype );
|
|
ConeGeometry.prototype.constructor = ConeGeometry;
|
|
|
|
// ConeBufferGeometry
|
|
|
|
function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
|
|
|
|
CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
|
|
|
|
this.type = 'ConeBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
height: height,
|
|
radialSegments: radialSegments,
|
|
heightSegments: heightSegments,
|
|
openEnded: openEnded,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
}
|
|
|
|
ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );
|
|
ConeBufferGeometry.prototype.constructor = ConeBufferGeometry;
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
* @author hughes
|
|
*/
|
|
|
|
// CircleGeometry
|
|
|
|
function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
|
|
|
|
Geometry.call( this );
|
|
|
|
this.type = 'CircleGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
segments: segments,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
|
|
this.mergeVertices();
|
|
|
|
}
|
|
|
|
CircleGeometry.prototype = Object.create( Geometry.prototype );
|
|
CircleGeometry.prototype.constructor = CircleGeometry;
|
|
|
|
// CircleBufferGeometry
|
|
|
|
function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'CircleBufferGeometry';
|
|
|
|
this.parameters = {
|
|
radius: radius,
|
|
segments: segments,
|
|
thetaStart: thetaStart,
|
|
thetaLength: thetaLength
|
|
};
|
|
|
|
radius = radius || 50;
|
|
segments = segments !== undefined ? Math.max( 3, segments ) : 8;
|
|
|
|
thetaStart = thetaStart !== undefined ? thetaStart : 0;
|
|
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
|
|
|
|
// buffers
|
|
|
|
var indices = [];
|
|
var vertices = [];
|
|
var normals = [];
|
|
var uvs = [];
|
|
|
|
// helper variables
|
|
|
|
var i, s;
|
|
var vertex = new Vector3();
|
|
var uv = new Vector2();
|
|
|
|
// center point
|
|
|
|
vertices.push( 0, 0, 0 );
|
|
normals.push( 0, 0, 1 );
|
|
uvs.push( 0.5, 0.5 );
|
|
|
|
for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {
|
|
|
|
var segment = thetaStart + s / segments * thetaLength;
|
|
|
|
// vertex
|
|
|
|
vertex.x = radius * Math.cos( segment );
|
|
vertex.y = radius * Math.sin( segment );
|
|
|
|
vertices.push( vertex.x, vertex.y, vertex.z );
|
|
|
|
// normal
|
|
|
|
normals.push( 0, 0, 1 );
|
|
|
|
// uvs
|
|
|
|
uv.x = ( vertices[ i ] / radius + 1 ) / 2;
|
|
uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
|
|
|
|
uvs.push( uv.x, uv.y );
|
|
|
|
}
|
|
|
|
// indices
|
|
|
|
for ( i = 1; i <= segments; i ++ ) {
|
|
|
|
indices.push( i, i + 1, 0 );
|
|
|
|
}
|
|
|
|
// build geometry
|
|
|
|
this.setIndex( indices );
|
|
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
|
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
|
|
}
|
|
|
|
CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
|
|
CircleBufferGeometry.prototype.constructor = CircleBufferGeometry;
|
|
|
|
|
|
|
|
var Geometries = Object.freeze({
|
|
WireframeGeometry: WireframeGeometry,
|
|
ParametricGeometry: ParametricGeometry,
|
|
ParametricBufferGeometry: ParametricBufferGeometry,
|
|
TetrahedronGeometry: TetrahedronGeometry,
|
|
TetrahedronBufferGeometry: TetrahedronBufferGeometry,
|
|
OctahedronGeometry: OctahedronGeometry,
|
|
OctahedronBufferGeometry: OctahedronBufferGeometry,
|
|
IcosahedronGeometry: IcosahedronGeometry,
|
|
IcosahedronBufferGeometry: IcosahedronBufferGeometry,
|
|
DodecahedronGeometry: DodecahedronGeometry,
|
|
DodecahedronBufferGeometry: DodecahedronBufferGeometry,
|
|
PolyhedronGeometry: PolyhedronGeometry,
|
|
PolyhedronBufferGeometry: PolyhedronBufferGeometry,
|
|
TubeGeometry: TubeGeometry,
|
|
TubeBufferGeometry: TubeBufferGeometry,
|
|
TorusKnotGeometry: TorusKnotGeometry,
|
|
TorusKnotBufferGeometry: TorusKnotBufferGeometry,
|
|
TorusGeometry: TorusGeometry,
|
|
TorusBufferGeometry: TorusBufferGeometry,
|
|
TextGeometry: TextGeometry,
|
|
TextBufferGeometry: TextBufferGeometry,
|
|
SphereGeometry: SphereGeometry,
|
|
SphereBufferGeometry: SphereBufferGeometry,
|
|
RingGeometry: RingGeometry,
|
|
RingBufferGeometry: RingBufferGeometry,
|
|
PlaneGeometry: PlaneGeometry,
|
|
PlaneBufferGeometry: PlaneBufferGeometry,
|
|
LatheGeometry: LatheGeometry,
|
|
LatheBufferGeometry: LatheBufferGeometry,
|
|
ShapeGeometry: ShapeGeometry,
|
|
ShapeBufferGeometry: ShapeBufferGeometry,
|
|
ExtrudeGeometry: ExtrudeGeometry,
|
|
ExtrudeBufferGeometry: ExtrudeBufferGeometry,
|
|
EdgesGeometry: EdgesGeometry,
|
|
ConeGeometry: ConeGeometry,
|
|
ConeBufferGeometry: ConeBufferGeometry,
|
|
CylinderGeometry: CylinderGeometry,
|
|
CylinderBufferGeometry: CylinderBufferGeometry,
|
|
CircleGeometry: CircleGeometry,
|
|
CircleBufferGeometry: CircleBufferGeometry,
|
|
BoxGeometry: BoxGeometry,
|
|
BoxBufferGeometry: BoxBufferGeometry
|
|
});
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*
|
|
* parameters = {
|
|
* opacity: <float>
|
|
* }
|
|
*/
|
|
|
|
function ShadowMaterial( parameters ) {
|
|
|
|
ShaderMaterial.call( this, {
|
|
uniforms: UniformsUtils.merge( [
|
|
UniformsLib.lights,
|
|
{
|
|
opacity: { value: 1.0 }
|
|
}
|
|
] ),
|
|
vertexShader: ShaderChunk[ 'shadow_vert' ],
|
|
fragmentShader: ShaderChunk[ 'shadow_frag' ]
|
|
} );
|
|
|
|
this.lights = true;
|
|
this.transparent = true;
|
|
|
|
Object.defineProperties( this, {
|
|
opacity: {
|
|
enumerable: true,
|
|
get: function () {
|
|
return this.uniforms.opacity.value;
|
|
},
|
|
set: function ( value ) {
|
|
this.uniforms.opacity.value = value;
|
|
}
|
|
}
|
|
} );
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
ShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );
|
|
ShadowMaterial.prototype.constructor = ShadowMaterial;
|
|
|
|
ShadowMaterial.prototype.isShadowMaterial = true;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function RawShaderMaterial( parameters ) {
|
|
|
|
ShaderMaterial.call( this, parameters );
|
|
|
|
this.type = 'RawShaderMaterial';
|
|
|
|
}
|
|
|
|
RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );
|
|
RawShaderMaterial.prototype.constructor = RawShaderMaterial;
|
|
|
|
RawShaderMaterial.prototype.isRawShaderMaterial = true;
|
|
|
|
/**
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* roughness: <float>,
|
|
* metalness: <float>,
|
|
* opacity: <float>,
|
|
*
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* lightMap: new THREE.Texture( <Image> ),
|
|
* lightMapIntensity: <float>
|
|
*
|
|
* aoMap: new THREE.Texture( <Image> ),
|
|
* aoMapIntensity: <float>
|
|
*
|
|
* emissive: <hex>,
|
|
* emissiveIntensity: <float>
|
|
* emissiveMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* bumpMap: new THREE.Texture( <Image> ),
|
|
* bumpScale: <float>,
|
|
*
|
|
* normalMap: new THREE.Texture( <Image> ),
|
|
* normalScale: <Vector2>,
|
|
*
|
|
* displacementMap: new THREE.Texture( <Image> ),
|
|
* displacementScale: <float>,
|
|
* displacementBias: <float>,
|
|
*
|
|
* roughnessMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* metalnessMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* alphaMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
|
|
* envMapIntensity: <float>
|
|
*
|
|
* refractionRatio: <float>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>,
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>,
|
|
* morphNormals: <bool>
|
|
* }
|
|
*/
|
|
|
|
function MeshStandardMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.defines = { 'STANDARD': '' };
|
|
|
|
this.type = 'MeshStandardMaterial';
|
|
|
|
this.color = new Color( 0xffffff ); // diffuse
|
|
this.roughness = 0.5;
|
|
this.metalness = 0.5;
|
|
|
|
this.map = null;
|
|
|
|
this.lightMap = null;
|
|
this.lightMapIntensity = 1.0;
|
|
|
|
this.aoMap = null;
|
|
this.aoMapIntensity = 1.0;
|
|
|
|
this.emissive = new Color( 0x000000 );
|
|
this.emissiveIntensity = 1.0;
|
|
this.emissiveMap = null;
|
|
|
|
this.bumpMap = null;
|
|
this.bumpScale = 1;
|
|
|
|
this.normalMap = null;
|
|
this.normalScale = new Vector2( 1, 1 );
|
|
|
|
this.displacementMap = null;
|
|
this.displacementScale = 1;
|
|
this.displacementBias = 0;
|
|
|
|
this.roughnessMap = null;
|
|
|
|
this.metalnessMap = null;
|
|
|
|
this.alphaMap = null;
|
|
|
|
this.envMap = null;
|
|
this.envMapIntensity = 1.0;
|
|
|
|
this.refractionRatio = 0.98;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
this.wireframeLinecap = 'round';
|
|
this.wireframeLinejoin = 'round';
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
this.morphNormals = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshStandardMaterial.prototype = Object.create( Material.prototype );
|
|
MeshStandardMaterial.prototype.constructor = MeshStandardMaterial;
|
|
|
|
MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
|
|
|
|
MeshStandardMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.defines = { 'STANDARD': '' };
|
|
|
|
this.color.copy( source.color );
|
|
this.roughness = source.roughness;
|
|
this.metalness = source.metalness;
|
|
|
|
this.map = source.map;
|
|
|
|
this.lightMap = source.lightMap;
|
|
this.lightMapIntensity = source.lightMapIntensity;
|
|
|
|
this.aoMap = source.aoMap;
|
|
this.aoMapIntensity = source.aoMapIntensity;
|
|
|
|
this.emissive.copy( source.emissive );
|
|
this.emissiveMap = source.emissiveMap;
|
|
this.emissiveIntensity = source.emissiveIntensity;
|
|
|
|
this.bumpMap = source.bumpMap;
|
|
this.bumpScale = source.bumpScale;
|
|
|
|
this.normalMap = source.normalMap;
|
|
this.normalScale.copy( source.normalScale );
|
|
|
|
this.displacementMap = source.displacementMap;
|
|
this.displacementScale = source.displacementScale;
|
|
this.displacementBias = source.displacementBias;
|
|
|
|
this.roughnessMap = source.roughnessMap;
|
|
|
|
this.metalnessMap = source.metalnessMap;
|
|
|
|
this.alphaMap = source.alphaMap;
|
|
|
|
this.envMap = source.envMap;
|
|
this.envMapIntensity = source.envMapIntensity;
|
|
|
|
this.refractionRatio = source.refractionRatio;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
this.wireframeLinecap = source.wireframeLinecap;
|
|
this.wireframeLinejoin = source.wireframeLinejoin;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
this.morphNormals = source.morphNormals;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*
|
|
* parameters = {
|
|
* reflectivity: <float>
|
|
* }
|
|
*/
|
|
|
|
function MeshPhysicalMaterial( parameters ) {
|
|
|
|
MeshStandardMaterial.call( this );
|
|
|
|
this.defines = { 'PHYSICAL': '' };
|
|
|
|
this.type = 'MeshPhysicalMaterial';
|
|
|
|
this.reflectivity = 0.5; // maps to F0 = 0.04
|
|
|
|
this.clearCoat = 0.0;
|
|
this.clearCoatRoughness = 0.0;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );
|
|
MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;
|
|
|
|
MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
|
|
|
|
MeshPhysicalMaterial.prototype.copy = function ( source ) {
|
|
|
|
MeshStandardMaterial.prototype.copy.call( this, source );
|
|
|
|
this.defines = { 'PHYSICAL': '' };
|
|
|
|
this.reflectivity = source.reflectivity;
|
|
|
|
this.clearCoat = source.clearCoat;
|
|
this.clearCoatRoughness = source.clearCoatRoughness;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* specular: <hex>,
|
|
* shininess: <float>,
|
|
* opacity: <float>,
|
|
*
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* lightMap: new THREE.Texture( <Image> ),
|
|
* lightMapIntensity: <float>
|
|
*
|
|
* aoMap: new THREE.Texture( <Image> ),
|
|
* aoMapIntensity: <float>
|
|
*
|
|
* emissive: <hex>,
|
|
* emissiveIntensity: <float>
|
|
* emissiveMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* bumpMap: new THREE.Texture( <Image> ),
|
|
* bumpScale: <float>,
|
|
*
|
|
* normalMap: new THREE.Texture( <Image> ),
|
|
* normalScale: <Vector2>,
|
|
*
|
|
* displacementMap: new THREE.Texture( <Image> ),
|
|
* displacementScale: <float>,
|
|
* displacementBias: <float>,
|
|
*
|
|
* specularMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* alphaMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
|
|
* combine: THREE.Multiply,
|
|
* reflectivity: <float>,
|
|
* refractionRatio: <float>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>,
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>,
|
|
* morphNormals: <bool>
|
|
* }
|
|
*/
|
|
|
|
function MeshPhongMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'MeshPhongMaterial';
|
|
|
|
this.color = new Color( 0xffffff ); // diffuse
|
|
this.specular = new Color( 0x111111 );
|
|
this.shininess = 30;
|
|
|
|
this.map = null;
|
|
|
|
this.lightMap = null;
|
|
this.lightMapIntensity = 1.0;
|
|
|
|
this.aoMap = null;
|
|
this.aoMapIntensity = 1.0;
|
|
|
|
this.emissive = new Color( 0x000000 );
|
|
this.emissiveIntensity = 1.0;
|
|
this.emissiveMap = null;
|
|
|
|
this.bumpMap = null;
|
|
this.bumpScale = 1;
|
|
|
|
this.normalMap = null;
|
|
this.normalScale = new Vector2( 1, 1 );
|
|
|
|
this.displacementMap = null;
|
|
this.displacementScale = 1;
|
|
this.displacementBias = 0;
|
|
|
|
this.specularMap = null;
|
|
|
|
this.alphaMap = null;
|
|
|
|
this.envMap = null;
|
|
this.combine = MultiplyOperation;
|
|
this.reflectivity = 1;
|
|
this.refractionRatio = 0.98;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
this.wireframeLinecap = 'round';
|
|
this.wireframeLinejoin = 'round';
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
this.morphNormals = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshPhongMaterial.prototype = Object.create( Material.prototype );
|
|
MeshPhongMaterial.prototype.constructor = MeshPhongMaterial;
|
|
|
|
MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
|
|
|
|
MeshPhongMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
this.specular.copy( source.specular );
|
|
this.shininess = source.shininess;
|
|
|
|
this.map = source.map;
|
|
|
|
this.lightMap = source.lightMap;
|
|
this.lightMapIntensity = source.lightMapIntensity;
|
|
|
|
this.aoMap = source.aoMap;
|
|
this.aoMapIntensity = source.aoMapIntensity;
|
|
|
|
this.emissive.copy( source.emissive );
|
|
this.emissiveMap = source.emissiveMap;
|
|
this.emissiveIntensity = source.emissiveIntensity;
|
|
|
|
this.bumpMap = source.bumpMap;
|
|
this.bumpScale = source.bumpScale;
|
|
|
|
this.normalMap = source.normalMap;
|
|
this.normalScale.copy( source.normalScale );
|
|
|
|
this.displacementMap = source.displacementMap;
|
|
this.displacementScale = source.displacementScale;
|
|
this.displacementBias = source.displacementBias;
|
|
|
|
this.specularMap = source.specularMap;
|
|
|
|
this.alphaMap = source.alphaMap;
|
|
|
|
this.envMap = source.envMap;
|
|
this.combine = source.combine;
|
|
this.reflectivity = source.reflectivity;
|
|
this.refractionRatio = source.refractionRatio;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
this.wireframeLinecap = source.wireframeLinecap;
|
|
this.wireframeLinejoin = source.wireframeLinejoin;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
this.morphNormals = source.morphNormals;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author takahirox / http://github.com/takahirox
|
|
*
|
|
* parameters = {
|
|
* gradientMap: new THREE.Texture( <Image> )
|
|
* }
|
|
*/
|
|
|
|
function MeshToonMaterial( parameters ) {
|
|
|
|
MeshPhongMaterial.call( this );
|
|
|
|
this.defines = { 'TOON': '' };
|
|
|
|
this.type = 'MeshToonMaterial';
|
|
|
|
this.gradientMap = null;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );
|
|
MeshToonMaterial.prototype.constructor = MeshToonMaterial;
|
|
|
|
MeshToonMaterial.prototype.isMeshToonMaterial = true;
|
|
|
|
MeshToonMaterial.prototype.copy = function ( source ) {
|
|
|
|
MeshPhongMaterial.prototype.copy.call( this, source );
|
|
|
|
this.gradientMap = source.gradientMap;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*
|
|
* parameters = {
|
|
* opacity: <float>,
|
|
*
|
|
* bumpMap: new THREE.Texture( <Image> ),
|
|
* bumpScale: <float>,
|
|
*
|
|
* normalMap: new THREE.Texture( <Image> ),
|
|
* normalScale: <Vector2>,
|
|
*
|
|
* displacementMap: new THREE.Texture( <Image> ),
|
|
* displacementScale: <float>,
|
|
* displacementBias: <float>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>,
|
|
* morphNormals: <bool>
|
|
* }
|
|
*/
|
|
|
|
function MeshNormalMaterial( parameters ) {
|
|
|
|
Material.call( this, parameters );
|
|
|
|
this.type = 'MeshNormalMaterial';
|
|
|
|
this.bumpMap = null;
|
|
this.bumpScale = 1;
|
|
|
|
this.normalMap = null;
|
|
this.normalScale = new Vector2( 1, 1 );
|
|
|
|
this.displacementMap = null;
|
|
this.displacementScale = 1;
|
|
this.displacementBias = 0;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
|
|
this.fog = false;
|
|
this.lights = false;
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
this.morphNormals = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshNormalMaterial.prototype = Object.create( Material.prototype );
|
|
MeshNormalMaterial.prototype.constructor = MeshNormalMaterial;
|
|
|
|
MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
|
|
|
|
MeshNormalMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.bumpMap = source.bumpMap;
|
|
this.bumpScale = source.bumpScale;
|
|
|
|
this.normalMap = source.normalMap;
|
|
this.normalScale.copy( source.normalScale );
|
|
|
|
this.displacementMap = source.displacementMap;
|
|
this.displacementScale = source.displacementScale;
|
|
this.displacementBias = source.displacementBias;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
this.morphNormals = source.morphNormals;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
*
|
|
* map: new THREE.Texture( <Image> ),
|
|
*
|
|
* lightMap: new THREE.Texture( <Image> ),
|
|
* lightMapIntensity: <float>
|
|
*
|
|
* aoMap: new THREE.Texture( <Image> ),
|
|
* aoMapIntensity: <float>
|
|
*
|
|
* emissive: <hex>,
|
|
* emissiveIntensity: <float>
|
|
* emissiveMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* specularMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* alphaMap: new THREE.Texture( <Image> ),
|
|
*
|
|
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
|
|
* combine: THREE.Multiply,
|
|
* reflectivity: <float>,
|
|
* refractionRatio: <float>,
|
|
*
|
|
* wireframe: <boolean>,
|
|
* wireframeLinewidth: <float>,
|
|
*
|
|
* skinning: <bool>,
|
|
* morphTargets: <bool>,
|
|
* morphNormals: <bool>
|
|
* }
|
|
*/
|
|
|
|
function MeshLambertMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'MeshLambertMaterial';
|
|
|
|
this.color = new Color( 0xffffff ); // diffuse
|
|
|
|
this.map = null;
|
|
|
|
this.lightMap = null;
|
|
this.lightMapIntensity = 1.0;
|
|
|
|
this.aoMap = null;
|
|
this.aoMapIntensity = 1.0;
|
|
|
|
this.emissive = new Color( 0x000000 );
|
|
this.emissiveIntensity = 1.0;
|
|
this.emissiveMap = null;
|
|
|
|
this.specularMap = null;
|
|
|
|
this.alphaMap = null;
|
|
|
|
this.envMap = null;
|
|
this.combine = MultiplyOperation;
|
|
this.reflectivity = 1;
|
|
this.refractionRatio = 0.98;
|
|
|
|
this.wireframe = false;
|
|
this.wireframeLinewidth = 1;
|
|
this.wireframeLinecap = 'round';
|
|
this.wireframeLinejoin = 'round';
|
|
|
|
this.skinning = false;
|
|
this.morphTargets = false;
|
|
this.morphNormals = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
MeshLambertMaterial.prototype = Object.create( Material.prototype );
|
|
MeshLambertMaterial.prototype.constructor = MeshLambertMaterial;
|
|
|
|
MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
|
|
|
|
MeshLambertMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
|
|
this.map = source.map;
|
|
|
|
this.lightMap = source.lightMap;
|
|
this.lightMapIntensity = source.lightMapIntensity;
|
|
|
|
this.aoMap = source.aoMap;
|
|
this.aoMapIntensity = source.aoMapIntensity;
|
|
|
|
this.emissive.copy( source.emissive );
|
|
this.emissiveMap = source.emissiveMap;
|
|
this.emissiveIntensity = source.emissiveIntensity;
|
|
|
|
this.specularMap = source.specularMap;
|
|
|
|
this.alphaMap = source.alphaMap;
|
|
|
|
this.envMap = source.envMap;
|
|
this.combine = source.combine;
|
|
this.reflectivity = source.reflectivity;
|
|
this.refractionRatio = source.refractionRatio;
|
|
|
|
this.wireframe = source.wireframe;
|
|
this.wireframeLinewidth = source.wireframeLinewidth;
|
|
this.wireframeLinecap = source.wireframeLinecap;
|
|
this.wireframeLinejoin = source.wireframeLinejoin;
|
|
|
|
this.skinning = source.skinning;
|
|
this.morphTargets = source.morphTargets;
|
|
this.morphNormals = source.morphNormals;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*
|
|
* parameters = {
|
|
* color: <hex>,
|
|
* opacity: <float>,
|
|
*
|
|
* linewidth: <float>,
|
|
*
|
|
* scale: <float>,
|
|
* dashSize: <float>,
|
|
* gapSize: <float>
|
|
* }
|
|
*/
|
|
|
|
function LineDashedMaterial( parameters ) {
|
|
|
|
Material.call( this );
|
|
|
|
this.type = 'LineDashedMaterial';
|
|
|
|
this.color = new Color( 0xffffff );
|
|
|
|
this.linewidth = 1;
|
|
|
|
this.scale = 1;
|
|
this.dashSize = 3;
|
|
this.gapSize = 1;
|
|
|
|
this.lights = false;
|
|
|
|
this.setValues( parameters );
|
|
|
|
}
|
|
|
|
LineDashedMaterial.prototype = Object.create( Material.prototype );
|
|
LineDashedMaterial.prototype.constructor = LineDashedMaterial;
|
|
|
|
LineDashedMaterial.prototype.isLineDashedMaterial = true;
|
|
|
|
LineDashedMaterial.prototype.copy = function ( source ) {
|
|
|
|
Material.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
|
|
this.linewidth = source.linewidth;
|
|
|
|
this.scale = source.scale;
|
|
this.dashSize = source.dashSize;
|
|
this.gapSize = source.gapSize;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
var Materials = Object.freeze({
|
|
ShadowMaterial: ShadowMaterial,
|
|
SpriteMaterial: SpriteMaterial,
|
|
RawShaderMaterial: RawShaderMaterial,
|
|
ShaderMaterial: ShaderMaterial,
|
|
PointsMaterial: PointsMaterial,
|
|
MeshPhysicalMaterial: MeshPhysicalMaterial,
|
|
MeshStandardMaterial: MeshStandardMaterial,
|
|
MeshPhongMaterial: MeshPhongMaterial,
|
|
MeshToonMaterial: MeshToonMaterial,
|
|
MeshNormalMaterial: MeshNormalMaterial,
|
|
MeshLambertMaterial: MeshLambertMaterial,
|
|
MeshDepthMaterial: MeshDepthMaterial,
|
|
MeshBasicMaterial: MeshBasicMaterial,
|
|
LineDashedMaterial: LineDashedMaterial,
|
|
LineBasicMaterial: LineBasicMaterial,
|
|
Material: Material
|
|
});
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
var Cache = {
|
|
|
|
enabled: false,
|
|
|
|
files: {},
|
|
|
|
add: function ( key, file ) {
|
|
|
|
if ( this.enabled === false ) return;
|
|
|
|
// console.log( 'THREE.Cache', 'Adding key:', key );
|
|
|
|
this.files[ key ] = file;
|
|
|
|
},
|
|
|
|
get: function ( key ) {
|
|
|
|
if ( this.enabled === false ) return;
|
|
|
|
// console.log( 'THREE.Cache', 'Checking key:', key );
|
|
|
|
return this.files[ key ];
|
|
|
|
},
|
|
|
|
remove: function ( key ) {
|
|
|
|
delete this.files[ key ];
|
|
|
|
},
|
|
|
|
clear: function () {
|
|
|
|
this.files = {};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function LoadingManager( onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
|
|
|
|
this.onStart = undefined;
|
|
this.onLoad = onLoad;
|
|
this.onProgress = onProgress;
|
|
this.onError = onError;
|
|
|
|
this.itemStart = function ( url ) {
|
|
|
|
itemsTotal ++;
|
|
|
|
if ( isLoading === false ) {
|
|
|
|
if ( scope.onStart !== undefined ) {
|
|
|
|
scope.onStart( url, itemsLoaded, itemsTotal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
isLoading = true;
|
|
|
|
};
|
|
|
|
this.itemEnd = function ( url ) {
|
|
|
|
itemsLoaded ++;
|
|
|
|
if ( scope.onProgress !== undefined ) {
|
|
|
|
scope.onProgress( url, itemsLoaded, itemsTotal );
|
|
|
|
}
|
|
|
|
if ( itemsLoaded === itemsTotal ) {
|
|
|
|
isLoading = false;
|
|
|
|
if ( scope.onLoad !== undefined ) {
|
|
|
|
scope.onLoad();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
this.itemError = function ( url ) {
|
|
|
|
if ( scope.onError !== undefined ) {
|
|
|
|
scope.onError( url );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
var DefaultLoadingManager = new LoadingManager();
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function FileLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( FileLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
if ( url === undefined ) url = '';
|
|
|
|
if ( this.path !== undefined ) url = this.path + url;
|
|
|
|
var scope = this;
|
|
|
|
var cached = Cache.get( url );
|
|
|
|
if ( cached !== undefined ) {
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|
setTimeout( function () {
|
|
|
|
if ( onLoad ) onLoad( cached );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
}, 0 );
|
|
|
|
return cached;
|
|
|
|
}
|
|
|
|
// Check for data: URI
|
|
var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
|
|
var dataUriRegexResult = url.match( dataUriRegex );
|
|
|
|
// Safari can not handle Data URIs through XMLHttpRequest so process manually
|
|
if ( dataUriRegexResult ) {
|
|
|
|
var mimeType = dataUriRegexResult[ 1 ];
|
|
var isBase64 = !! dataUriRegexResult[ 2 ];
|
|
var data = dataUriRegexResult[ 3 ];
|
|
|
|
data = window.decodeURIComponent( data );
|
|
|
|
if ( isBase64 ) data = window.atob( data );
|
|
|
|
try {
|
|
|
|
var response;
|
|
var responseType = ( this.responseType || '' ).toLowerCase();
|
|
|
|
switch ( responseType ) {
|
|
|
|
case 'arraybuffer':
|
|
case 'blob':
|
|
|
|
response = new ArrayBuffer( data.length );
|
|
|
|
var view = new Uint8Array( response );
|
|
|
|
for ( var i = 0; i < data.length; i ++ ) {
|
|
|
|
view[ i ] = data.charCodeAt( i );
|
|
|
|
}
|
|
|
|
if ( responseType === 'blob' ) {
|
|
|
|
response = new Blob( [ response ], { type: mimeType } );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'document':
|
|
|
|
var parser = new DOMParser();
|
|
response = parser.parseFromString( data, mimeType );
|
|
|
|
break;
|
|
|
|
case 'json':
|
|
|
|
response = JSON.parse( data );
|
|
|
|
break;
|
|
|
|
default: // 'text' or other
|
|
|
|
response = data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Wait for next browser tick
|
|
window.setTimeout( function () {
|
|
|
|
if ( onLoad ) onLoad( response );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
}, 0 );
|
|
|
|
} catch ( error ) {
|
|
|
|
// Wait for next browser tick
|
|
window.setTimeout( function () {
|
|
|
|
if ( onError ) onError( error );
|
|
|
|
scope.manager.itemEnd( url );
|
|
scope.manager.itemError( url );
|
|
|
|
}, 0 );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var request = new XMLHttpRequest();
|
|
request.open( 'GET', url, true );
|
|
|
|
request.addEventListener( 'load', function ( event ) {
|
|
|
|
var response = event.target.response;
|
|
|
|
Cache.add( url, response );
|
|
|
|
if ( this.status === 200 ) {
|
|
|
|
if ( onLoad ) onLoad( response );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
} else if ( this.status === 0 ) {
|
|
|
|
// Some browsers return HTTP Status 0 when using non-http protocol
|
|
// e.g. 'file://' or 'data://'. Handle as success.
|
|
|
|
console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
|
|
|
|
if ( onLoad ) onLoad( response );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
} else {
|
|
|
|
if ( onError ) onError( event );
|
|
|
|
scope.manager.itemEnd( url );
|
|
scope.manager.itemError( url );
|
|
|
|
}
|
|
|
|
}, false );
|
|
|
|
if ( onProgress !== undefined ) {
|
|
|
|
request.addEventListener( 'progress', function ( event ) {
|
|
|
|
onProgress( event );
|
|
|
|
}, false );
|
|
|
|
}
|
|
|
|
request.addEventListener( 'error', function ( event ) {
|
|
|
|
if ( onError ) onError( event );
|
|
|
|
scope.manager.itemEnd( url );
|
|
scope.manager.itemError( url );
|
|
|
|
}, false );
|
|
|
|
if ( this.responseType !== undefined ) request.responseType = this.responseType;
|
|
if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
|
|
|
|
if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
|
|
|
|
for ( var header in this.requestHeader ) {
|
|
|
|
request.setRequestHeader( header, this.requestHeader[ header ] );
|
|
|
|
}
|
|
|
|
request.send( null );
|
|
|
|
}
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|
return request;
|
|
|
|
},
|
|
|
|
setPath: function ( value ) {
|
|
|
|
this.path = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setResponseType: function ( value ) {
|
|
|
|
this.responseType = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setWithCredentials: function ( value ) {
|
|
|
|
this.withCredentials = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setMimeType: function ( value ) {
|
|
|
|
this.mimeType = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setRequestHeader: function ( value ) {
|
|
|
|
this.requestHeader = value;
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*
|
|
* Abstract Base class to block based textures loader (dds, pvr, ...)
|
|
*/
|
|
|
|
function CompressedTextureLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
// override in sub classes
|
|
this._parser = null;
|
|
|
|
}
|
|
|
|
Object.assign( CompressedTextureLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var images = [];
|
|
|
|
var texture = new CompressedTexture();
|
|
texture.image = images;
|
|
|
|
var loader = new FileLoader( this.manager );
|
|
loader.setPath( this.path );
|
|
loader.setResponseType( 'arraybuffer' );
|
|
|
|
function loadTexture( i ) {
|
|
|
|
loader.load( url[ i ], function ( buffer ) {
|
|
|
|
var texDatas = scope._parser( buffer, true );
|
|
|
|
images[ i ] = {
|
|
width: texDatas.width,
|
|
height: texDatas.height,
|
|
format: texDatas.format,
|
|
mipmaps: texDatas.mipmaps
|
|
};
|
|
|
|
loaded += 1;
|
|
|
|
if ( loaded === 6 ) {
|
|
|
|
if ( texDatas.mipmapCount === 1 )
|
|
texture.minFilter = LinearFilter;
|
|
|
|
texture.format = texDatas.format;
|
|
texture.needsUpdate = true;
|
|
|
|
if ( onLoad ) onLoad( texture );
|
|
|
|
}
|
|
|
|
}, onProgress, onError );
|
|
|
|
}
|
|
|
|
if ( Array.isArray( url ) ) {
|
|
|
|
var loaded = 0;
|
|
|
|
for ( var i = 0, il = url.length; i < il; ++ i ) {
|
|
|
|
loadTexture( i );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// compressed cubemap texture stored in a single DDS file
|
|
|
|
loader.load( url, function ( buffer ) {
|
|
|
|
var texDatas = scope._parser( buffer, true );
|
|
|
|
if ( texDatas.isCubemap ) {
|
|
|
|
var faces = texDatas.mipmaps.length / texDatas.mipmapCount;
|
|
|
|
for ( var f = 0; f < faces; f ++ ) {
|
|
|
|
images[ f ] = { mipmaps : [] };
|
|
|
|
for ( var i = 0; i < texDatas.mipmapCount; i ++ ) {
|
|
|
|
images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
|
|
images[ f ].format = texDatas.format;
|
|
images[ f ].width = texDatas.width;
|
|
images[ f ].height = texDatas.height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
texture.image.width = texDatas.width;
|
|
texture.image.height = texDatas.height;
|
|
texture.mipmaps = texDatas.mipmaps;
|
|
|
|
}
|
|
|
|
if ( texDatas.mipmapCount === 1 ) {
|
|
|
|
texture.minFilter = LinearFilter;
|
|
|
|
}
|
|
|
|
texture.format = texDatas.format;
|
|
texture.needsUpdate = true;
|
|
|
|
if ( onLoad ) onLoad( texture );
|
|
|
|
}, onProgress, onError );
|
|
|
|
}
|
|
|
|
return texture;
|
|
|
|
},
|
|
|
|
setPath: function ( value ) {
|
|
|
|
this.path = value;
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author Nikos M. / https://github.com/foo123/
|
|
*
|
|
* Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
|
|
*/
|
|
|
|
function DataTextureLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
// override in sub classes
|
|
this._parser = null;
|
|
|
|
}
|
|
|
|
Object.assign( DataTextureLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var texture = new DataTexture();
|
|
|
|
var loader = new FileLoader( this.manager );
|
|
loader.setResponseType( 'arraybuffer' );
|
|
|
|
loader.load( url, function ( buffer ) {
|
|
|
|
var texData = scope._parser( buffer );
|
|
|
|
if ( ! texData ) return;
|
|
|
|
if ( undefined !== texData.image ) {
|
|
|
|
texture.image = texData.image;
|
|
|
|
} else if ( undefined !== texData.data ) {
|
|
|
|
texture.image.width = texData.width;
|
|
texture.image.height = texData.height;
|
|
texture.image.data = texData.data;
|
|
|
|
}
|
|
|
|
texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;
|
|
texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;
|
|
|
|
texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;
|
|
texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;
|
|
|
|
texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;
|
|
|
|
if ( undefined !== texData.format ) {
|
|
|
|
texture.format = texData.format;
|
|
|
|
}
|
|
if ( undefined !== texData.type ) {
|
|
|
|
texture.type = texData.type;
|
|
|
|
}
|
|
|
|
if ( undefined !== texData.mipmaps ) {
|
|
|
|
texture.mipmaps = texData.mipmaps;
|
|
|
|
}
|
|
|
|
if ( 1 === texData.mipmapCount ) {
|
|
|
|
texture.minFilter = LinearFilter;
|
|
|
|
}
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
if ( onLoad ) onLoad( texture, texData );
|
|
|
|
}, onProgress, onError );
|
|
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function ImageLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( ImageLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
if ( url === undefined ) url = '';
|
|
|
|
if ( this.path !== undefined ) url = this.path + url;
|
|
|
|
var scope = this;
|
|
|
|
var cached = Cache.get( url );
|
|
|
|
if ( cached !== undefined ) {
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|
setTimeout( function () {
|
|
|
|
if ( onLoad ) onLoad( cached );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
}, 0 );
|
|
|
|
return cached;
|
|
|
|
}
|
|
|
|
var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
|
|
|
|
image.addEventListener( 'load', function () {
|
|
|
|
Cache.add( url, this );
|
|
|
|
if ( onLoad ) onLoad( this );
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
}, false );
|
|
|
|
/*
|
|
image.addEventListener( 'progress', function ( event ) {
|
|
|
|
if ( onProgress ) onProgress( event );
|
|
|
|
}, false );
|
|
*/
|
|
|
|
image.addEventListener( 'error', function ( event ) {
|
|
|
|
if ( onError ) onError( event );
|
|
|
|
scope.manager.itemEnd( url );
|
|
scope.manager.itemError( url );
|
|
|
|
}, false );
|
|
|
|
if ( url.substr( 0, 5 ) !== 'data:' ) {
|
|
|
|
if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
|
|
|
|
}
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|
image.src = url;
|
|
|
|
return image;
|
|
|
|
},
|
|
|
|
setCrossOrigin: function ( value ) {
|
|
|
|
this.crossOrigin = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setPath: function ( value ) {
|
|
|
|
this.path = value;
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function CubeTextureLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( CubeTextureLoader.prototype, {
|
|
|
|
load: function ( urls, onLoad, onProgress, onError ) {
|
|
|
|
var texture = new CubeTexture();
|
|
|
|
var loader = new ImageLoader( this.manager );
|
|
loader.setCrossOrigin( this.crossOrigin );
|
|
loader.setPath( this.path );
|
|
|
|
var loaded = 0;
|
|
|
|
function loadTexture( i ) {
|
|
|
|
loader.load( urls[ i ], function ( image ) {
|
|
|
|
texture.images[ i ] = image;
|
|
|
|
loaded ++;
|
|
|
|
if ( loaded === 6 ) {
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
if ( onLoad ) onLoad( texture );
|
|
|
|
}
|
|
|
|
}, undefined, onError );
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < urls.length; ++ i ) {
|
|
|
|
loadTexture( i );
|
|
|
|
}
|
|
|
|
return texture;
|
|
|
|
},
|
|
|
|
setCrossOrigin: function ( value ) {
|
|
|
|
this.crossOrigin = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setPath: function ( value ) {
|
|
|
|
this.path = value;
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function TextureLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( TextureLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var loader = new ImageLoader( this.manager );
|
|
loader.setCrossOrigin( this.crossOrigin );
|
|
loader.setPath( this.path );
|
|
|
|
var texture = new Texture();
|
|
texture.image = loader.load( url, function () {
|
|
|
|
// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
|
|
var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
|
|
|
|
texture.format = isJPEG ? RGBFormat : RGBAFormat;
|
|
texture.needsUpdate = true;
|
|
|
|
if ( onLoad !== undefined ) {
|
|
|
|
onLoad( texture );
|
|
|
|
}
|
|
|
|
}, onProgress, onError );
|
|
|
|
return texture;
|
|
|
|
},
|
|
|
|
setCrossOrigin: function ( value ) {
|
|
|
|
this.crossOrigin = value;
|
|
return this;
|
|
|
|
},
|
|
|
|
setPath: function ( value ) {
|
|
|
|
this.path = value;
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Light( color, intensity ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Light';
|
|
|
|
this.color = new Color( color );
|
|
this.intensity = intensity !== undefined ? intensity : 1;
|
|
|
|
this.receiveShadow = undefined;
|
|
|
|
}
|
|
|
|
Light.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Light,
|
|
|
|
isLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Object3D.prototype.copy.call( this, source );
|
|
|
|
this.color.copy( source.color );
|
|
this.intensity = source.intensity;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Object3D.prototype.toJSON.call( this, meta );
|
|
|
|
data.object.color = this.color.getHex();
|
|
data.object.intensity = this.intensity;
|
|
|
|
if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();
|
|
|
|
if ( this.distance !== undefined ) data.object.distance = this.distance;
|
|
if ( this.angle !== undefined ) data.object.angle = this.angle;
|
|
if ( this.decay !== undefined ) data.object.decay = this.decay;
|
|
if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;
|
|
|
|
if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function HemisphereLight( skyColor, groundColor, intensity ) {
|
|
|
|
Light.call( this, skyColor, intensity );
|
|
|
|
this.type = 'HemisphereLight';
|
|
|
|
this.castShadow = undefined;
|
|
|
|
this.position.copy( Object3D.DefaultUp );
|
|
this.updateMatrix();
|
|
|
|
this.groundColor = new Color( groundColor );
|
|
|
|
}
|
|
|
|
HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: HemisphereLight,
|
|
|
|
isHemisphereLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Light.prototype.copy.call( this, source );
|
|
|
|
this.groundColor.copy( source.groundColor );
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function LightShadow( camera ) {
|
|
|
|
this.camera = camera;
|
|
|
|
this.bias = 0;
|
|
this.radius = 1;
|
|
|
|
this.mapSize = new Vector2( 512, 512 );
|
|
|
|
this.map = null;
|
|
this.matrix = new Matrix4();
|
|
|
|
}
|
|
|
|
Object.assign( LightShadow.prototype, {
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.camera = source.camera.clone();
|
|
|
|
this.bias = source.bias;
|
|
this.radius = source.radius;
|
|
|
|
this.mapSize.copy( source.mapSize );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
toJSON: function () {
|
|
|
|
var object = {};
|
|
|
|
if ( this.bias !== 0 ) object.bias = this.bias;
|
|
if ( this.radius !== 1 ) object.radius = this.radius;
|
|
if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();
|
|
|
|
object.camera = this.camera.toJSON( false ).object;
|
|
delete object.camera.matrix;
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function SpotLightShadow() {
|
|
|
|
LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
|
|
|
|
}
|
|
|
|
SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
|
|
|
|
constructor: SpotLightShadow,
|
|
|
|
isSpotLightShadow: true,
|
|
|
|
update: function ( light ) {
|
|
|
|
var camera = this.camera;
|
|
|
|
var fov = _Math.RAD2DEG * 2 * light.angle;
|
|
var aspect = this.mapSize.width / this.mapSize.height;
|
|
var far = light.distance || camera.far;
|
|
|
|
if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
|
|
|
|
camera.fov = fov;
|
|
camera.aspect = aspect;
|
|
camera.far = far;
|
|
camera.updateProjectionMatrix();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
|
|
|
|
Light.call( this, color, intensity );
|
|
|
|
this.type = 'SpotLight';
|
|
|
|
this.position.copy( Object3D.DefaultUp );
|
|
this.updateMatrix();
|
|
|
|
this.target = new Object3D();
|
|
|
|
Object.defineProperty( this, 'power', {
|
|
get: function () {
|
|
// intensity = power per solid angle.
|
|
// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
|
|
return this.intensity * Math.PI;
|
|
},
|
|
set: function ( power ) {
|
|
// intensity = power per solid angle.
|
|
// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
|
|
this.intensity = power / Math.PI;
|
|
}
|
|
} );
|
|
|
|
this.distance = ( distance !== undefined ) ? distance : 0;
|
|
this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
|
|
this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
|
|
this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
|
|
|
|
this.shadow = new SpotLightShadow();
|
|
|
|
}
|
|
|
|
SpotLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: SpotLight,
|
|
|
|
isSpotLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Light.prototype.copy.call( this, source );
|
|
|
|
this.distance = source.distance;
|
|
this.angle = source.angle;
|
|
this.penumbra = source.penumbra;
|
|
this.decay = source.decay;
|
|
|
|
this.target = source.target.clone();
|
|
|
|
this.shadow = source.shadow.clone();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
|
|
function PointLight( color, intensity, distance, decay ) {
|
|
|
|
Light.call( this, color, intensity );
|
|
|
|
this.type = 'PointLight';
|
|
|
|
Object.defineProperty( this, 'power', {
|
|
get: function () {
|
|
// intensity = power per solid angle.
|
|
// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
|
|
return this.intensity * 4 * Math.PI;
|
|
|
|
},
|
|
set: function ( power ) {
|
|
// intensity = power per solid angle.
|
|
// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
|
|
this.intensity = power / ( 4 * Math.PI );
|
|
}
|
|
} );
|
|
|
|
this.distance = ( distance !== undefined ) ? distance : 0;
|
|
this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
|
|
|
|
this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );
|
|
|
|
}
|
|
|
|
PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: PointLight,
|
|
|
|
isPointLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Light.prototype.copy.call( this, source );
|
|
|
|
this.distance = source.distance;
|
|
this.decay = source.decay;
|
|
|
|
this.shadow = source.shadow.clone();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function DirectionalLightShadow( ) {
|
|
|
|
LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
|
|
|
|
}
|
|
|
|
DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
|
|
|
|
constructor: DirectionalLightShadow
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function DirectionalLight( color, intensity ) {
|
|
|
|
Light.call( this, color, intensity );
|
|
|
|
this.type = 'DirectionalLight';
|
|
|
|
this.position.copy( Object3D.DefaultUp );
|
|
this.updateMatrix();
|
|
|
|
this.target = new Object3D();
|
|
|
|
this.shadow = new DirectionalLightShadow();
|
|
|
|
}
|
|
|
|
DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: DirectionalLight,
|
|
|
|
isDirectionalLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Light.prototype.copy.call( this, source );
|
|
|
|
this.target = source.target.clone();
|
|
|
|
this.shadow = source.shadow.clone();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function AmbientLight( color, intensity ) {
|
|
|
|
Light.call( this, color, intensity );
|
|
|
|
this.type = 'AmbientLight';
|
|
|
|
this.castShadow = undefined;
|
|
|
|
}
|
|
|
|
AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: AmbientLight,
|
|
|
|
isAmbientLight: true
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author abelnation / http://github.com/abelnation
|
|
*/
|
|
|
|
function RectAreaLight( color, intensity, width, height ) {
|
|
|
|
Light.call( this, color, intensity );
|
|
|
|
this.type = 'RectAreaLight';
|
|
|
|
this.position.set( 0, 1, 0 );
|
|
this.updateMatrix();
|
|
|
|
this.width = ( width !== undefined ) ? width : 10;
|
|
this.height = ( height !== undefined ) ? height : 10;
|
|
|
|
// TODO (abelnation): distance/decay
|
|
|
|
// TODO (abelnation): update method for RectAreaLight to update transform to lookat target
|
|
|
|
// TODO (abelnation): shadows
|
|
|
|
}
|
|
|
|
// TODO (abelnation): RectAreaLight update when light shape is changed
|
|
RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {
|
|
|
|
constructor: RectAreaLight,
|
|
|
|
isRectAreaLight: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
Light.prototype.copy.call( this, source );
|
|
|
|
this.width = source.width;
|
|
this.height = source.height;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
toJSON: function ( meta ) {
|
|
|
|
var data = Light.prototype.toJSON.call( this, meta );
|
|
|
|
data.object.width = this.width;
|
|
data.object.height = this.height;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author tschw
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
*/
|
|
|
|
var AnimationUtils = {
|
|
|
|
// same as Array.prototype.slice, but also works on typed arrays
|
|
arraySlice: function ( array, from, to ) {
|
|
|
|
if ( AnimationUtils.isTypedArray( array ) ) {
|
|
|
|
// in ios9 array.subarray(from, undefined) will return empty array
|
|
// but array.subarray(from) or array.subarray(from, len) is correct
|
|
return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
|
|
|
|
}
|
|
|
|
return array.slice( from, to );
|
|
|
|
},
|
|
|
|
// converts an array to a specific type
|
|
convertArray: function ( array, type, forceClone ) {
|
|
|
|
if ( ! array || // let 'undefined' and 'null' pass
|
|
! forceClone && array.constructor === type ) return array;
|
|
|
|
if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
|
|
|
|
return new type( array ); // create typed array
|
|
|
|
}
|
|
|
|
return Array.prototype.slice.call( array ); // create Array
|
|
|
|
},
|
|
|
|
isTypedArray: function ( object ) {
|
|
|
|
return ArrayBuffer.isView( object ) &&
|
|
! ( object instanceof DataView );
|
|
|
|
},
|
|
|
|
// returns an array by which times and values can be sorted
|
|
getKeyframeOrder: function ( times ) {
|
|
|
|
function compareTime( i, j ) {
|
|
|
|
return times[ i ] - times[ j ];
|
|
|
|
}
|
|
|
|
var n = times.length;
|
|
var result = new Array( n );
|
|
for ( var i = 0; i !== n; ++ i ) result[ i ] = i;
|
|
|
|
result.sort( compareTime );
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
// uses the array previously returned by 'getKeyframeOrder' to sort data
|
|
sortedArray: function ( values, stride, order ) {
|
|
|
|
var nValues = values.length;
|
|
var result = new values.constructor( nValues );
|
|
|
|
for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
|
|
|
|
var srcOffset = order[ i ] * stride;
|
|
|
|
for ( var j = 0; j !== stride; ++ j ) {
|
|
|
|
result[ dstOffset ++ ] = values[ srcOffset + j ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
// function for parsing AOS keyframe formats
|
|
flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
|
|
|
|
var i = 1, key = jsonKeys[ 0 ];
|
|
|
|
while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
|
|
|
|
key = jsonKeys[ i ++ ];
|
|
|
|
}
|
|
|
|
if ( key === undefined ) return; // no data
|
|
|
|
var value = key[ valuePropertyName ];
|
|
if ( value === undefined ) return; // no data
|
|
|
|
if ( Array.isArray( value ) ) {
|
|
|
|
do {
|
|
|
|
value = key[ valuePropertyName ];
|
|
|
|
if ( value !== undefined ) {
|
|
|
|
times.push( key.time );
|
|
values.push.apply( values, value ); // push all elements
|
|
|
|
}
|
|
|
|
key = jsonKeys[ i ++ ];
|
|
|
|
} while ( key !== undefined );
|
|
|
|
} else if ( value.toArray !== undefined ) {
|
|
|
|
// ...assume THREE.Math-ish
|
|
|
|
do {
|
|
|
|
value = key[ valuePropertyName ];
|
|
|
|
if ( value !== undefined ) {
|
|
|
|
times.push( key.time );
|
|
value.toArray( values, values.length );
|
|
|
|
}
|
|
|
|
key = jsonKeys[ i ++ ];
|
|
|
|
} while ( key !== undefined );
|
|
|
|
} else {
|
|
|
|
// otherwise push as-is
|
|
|
|
do {
|
|
|
|
value = key[ valuePropertyName ];
|
|
|
|
if ( value !== undefined ) {
|
|
|
|
times.push( key.time );
|
|
values.push( value );
|
|
|
|
}
|
|
|
|
key = jsonKeys[ i ++ ];
|
|
|
|
} while ( key !== undefined );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Abstract base class of interpolants over parametric samples.
|
|
*
|
|
* The parameter domain is one dimensional, typically the time or a path
|
|
* along a curve defined by the data.
|
|
*
|
|
* The sample values can have any dimensionality and derived classes may
|
|
* apply special interpretations to the data.
|
|
*
|
|
* This class provides the interval seek in a Template Method, deferring
|
|
* the actual interpolation to derived classes.
|
|
*
|
|
* Time complexity is O(1) for linear access crossing at most two points
|
|
* and O(log N) for random access, where N is the number of positions.
|
|
*
|
|
* References:
|
|
*
|
|
* http://www.oodesign.com/template-method-pattern.html
|
|
*
|
|
* @author tschw
|
|
*/
|
|
|
|
function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
|
|
|
this.parameterPositions = parameterPositions;
|
|
this._cachedIndex = 0;
|
|
|
|
this.resultBuffer = resultBuffer !== undefined ?
|
|
resultBuffer : new sampleValues.constructor( sampleSize );
|
|
this.sampleValues = sampleValues;
|
|
this.valueSize = sampleSize;
|
|
|
|
}
|
|
|
|
Object.assign( Interpolant.prototype, {
|
|
|
|
evaluate: function( t ) {
|
|
|
|
var pp = this.parameterPositions,
|
|
i1 = this._cachedIndex,
|
|
|
|
t1 = pp[ i1 ],
|
|
t0 = pp[ i1 - 1 ];
|
|
|
|
validate_interval: {
|
|
|
|
seek: {
|
|
|
|
var right;
|
|
|
|
linear_scan: {
|
|
//- See http://jsperf.com/comparison-to-undefined/3
|
|
//- slower code:
|
|
//-
|
|
//- if ( t >= t1 || t1 === undefined ) {
|
|
forward_scan: if ( ! ( t < t1 ) ) {
|
|
|
|
for ( var giveUpAt = i1 + 2; ;) {
|
|
|
|
if ( t1 === undefined ) {
|
|
|
|
if ( t < t0 ) break forward_scan;
|
|
|
|
// after end
|
|
|
|
i1 = pp.length;
|
|
this._cachedIndex = i1;
|
|
return this.afterEnd_( i1 - 1, t, t0 );
|
|
|
|
}
|
|
|
|
if ( i1 === giveUpAt ) break; // this loop
|
|
|
|
t0 = t1;
|
|
t1 = pp[ ++ i1 ];
|
|
|
|
if ( t < t1 ) {
|
|
|
|
// we have arrived at the sought interval
|
|
break seek;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// prepare binary search on the right side of the index
|
|
right = pp.length;
|
|
break linear_scan;
|
|
|
|
}
|
|
|
|
//- slower code:
|
|
//- if ( t < t0 || t0 === undefined ) {
|
|
if ( ! ( t >= t0 ) ) {
|
|
|
|
// looping?
|
|
|
|
var t1global = pp[ 1 ];
|
|
|
|
if ( t < t1global ) {
|
|
|
|
i1 = 2; // + 1, using the scan for the details
|
|
t0 = t1global;
|
|
|
|
}
|
|
|
|
// linear reverse scan
|
|
|
|
for ( var giveUpAt = i1 - 2; ;) {
|
|
|
|
if ( t0 === undefined ) {
|
|
|
|
// before start
|
|
|
|
this._cachedIndex = 0;
|
|
return this.beforeStart_( 0, t, t1 );
|
|
|
|
}
|
|
|
|
if ( i1 === giveUpAt ) break; // this loop
|
|
|
|
t1 = t0;
|
|
t0 = pp[ -- i1 - 1 ];
|
|
|
|
if ( t >= t0 ) {
|
|
|
|
// we have arrived at the sought interval
|
|
break seek;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// prepare binary search on the left side of the index
|
|
right = i1;
|
|
i1 = 0;
|
|
break linear_scan;
|
|
|
|
}
|
|
|
|
// the interval is valid
|
|
|
|
break validate_interval;
|
|
|
|
} // linear scan
|
|
|
|
// binary search
|
|
|
|
while ( i1 < right ) {
|
|
|
|
var mid = ( i1 + right ) >>> 1;
|
|
|
|
if ( t < pp[ mid ] ) {
|
|
|
|
right = mid;
|
|
|
|
} else {
|
|
|
|
i1 = mid + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t1 = pp[ i1 ];
|
|
t0 = pp[ i1 - 1 ];
|
|
|
|
// check boundary cases, again
|
|
|
|
if ( t0 === undefined ) {
|
|
|
|
this._cachedIndex = 0;
|
|
return this.beforeStart_( 0, t, t1 );
|
|
|
|
}
|
|
|
|
if ( t1 === undefined ) {
|
|
|
|
i1 = pp.length;
|
|
this._cachedIndex = i1;
|
|
return this.afterEnd_( i1 - 1, t0, t );
|
|
|
|
}
|
|
|
|
} // seek
|
|
|
|
this._cachedIndex = i1;
|
|
|
|
this.intervalChanged_( i1, t0, t1 );
|
|
|
|
} // validate_interval
|
|
|
|
return this.interpolate_( i1, t0, t, t1 );
|
|
|
|
},
|
|
|
|
settings: null, // optional, subclass-specific settings structure
|
|
// Note: The indirection allows central control of many interpolants.
|
|
|
|
// --- Protected interface
|
|
|
|
DefaultSettings_: {},
|
|
|
|
getSettings_: function() {
|
|
|
|
return this.settings || this.DefaultSettings_;
|
|
|
|
},
|
|
|
|
copySampleValue_: function( index ) {
|
|
|
|
// copies a sample value to the result buffer
|
|
|
|
var result = this.resultBuffer,
|
|
values = this.sampleValues,
|
|
stride = this.valueSize,
|
|
offset = index * stride;
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
result[ i ] = values[ offset + i ];
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
// Template methods for derived classes:
|
|
|
|
interpolate_: function( i1, t0, t, t1 ) {
|
|
|
|
throw new Error( "call to abstract method" );
|
|
// implementations shall return this.resultBuffer
|
|
|
|
},
|
|
|
|
intervalChanged_: function( i1, t0, t1 ) {
|
|
|
|
// empty
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
//!\ DECLARE ALIAS AFTER assign prototype !
|
|
Object.assign( Interpolant.prototype, {
|
|
|
|
//( 0, t, t0 ), returns this.resultBuffer
|
|
beforeStart_: Interpolant.prototype.copySampleValue_,
|
|
|
|
//( N-1, tN-1, t ), returns this.resultBuffer
|
|
afterEnd_: Interpolant.prototype.copySampleValue_,
|
|
|
|
} );
|
|
|
|
/**
|
|
* Fast and simple cubic spline interpolant.
|
|
*
|
|
* It was derived from a Hermitian construction setting the first derivative
|
|
* at each sample position to the linear slope between neighboring positions
|
|
* over their parameter interval.
|
|
*
|
|
* @author tschw
|
|
*/
|
|
|
|
function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
|
|
|
Interpolant.call(
|
|
this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
|
|
|
this._weightPrev = -0;
|
|
this._offsetPrev = -0;
|
|
this._weightNext = -0;
|
|
this._offsetNext = -0;
|
|
|
|
}
|
|
|
|
CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
|
|
|
constructor: CubicInterpolant,
|
|
|
|
DefaultSettings_: {
|
|
|
|
endingStart: ZeroCurvatureEnding,
|
|
endingEnd: ZeroCurvatureEnding
|
|
|
|
},
|
|
|
|
intervalChanged_: function( i1, t0, t1 ) {
|
|
|
|
var pp = this.parameterPositions,
|
|
iPrev = i1 - 2,
|
|
iNext = i1 + 1,
|
|
|
|
tPrev = pp[ iPrev ],
|
|
tNext = pp[ iNext ];
|
|
|
|
if ( tPrev === undefined ) {
|
|
|
|
switch ( this.getSettings_().endingStart ) {
|
|
|
|
case ZeroSlopeEnding:
|
|
|
|
// f'(t0) = 0
|
|
iPrev = i1;
|
|
tPrev = 2 * t0 - t1;
|
|
|
|
break;
|
|
|
|
case WrapAroundEnding:
|
|
|
|
// use the other end of the curve
|
|
iPrev = pp.length - 2;
|
|
tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
|
|
|
|
break;
|
|
|
|
default: // ZeroCurvatureEnding
|
|
|
|
// f''(t0) = 0 a.k.a. Natural Spline
|
|
iPrev = i1;
|
|
tPrev = t1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( tNext === undefined ) {
|
|
|
|
switch ( this.getSettings_().endingEnd ) {
|
|
|
|
case ZeroSlopeEnding:
|
|
|
|
// f'(tN) = 0
|
|
iNext = i1;
|
|
tNext = 2 * t1 - t0;
|
|
|
|
break;
|
|
|
|
case WrapAroundEnding:
|
|
|
|
// use the other end of the curve
|
|
iNext = 1;
|
|
tNext = t1 + pp[ 1 ] - pp[ 0 ];
|
|
|
|
break;
|
|
|
|
default: // ZeroCurvatureEnding
|
|
|
|
// f''(tN) = 0, a.k.a. Natural Spline
|
|
iNext = i1 - 1;
|
|
tNext = t0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var halfDt = ( t1 - t0 ) * 0.5,
|
|
stride = this.valueSize;
|
|
|
|
this._weightPrev = halfDt / ( t0 - tPrev );
|
|
this._weightNext = halfDt / ( tNext - t1 );
|
|
this._offsetPrev = iPrev * stride;
|
|
this._offsetNext = iNext * stride;
|
|
|
|
},
|
|
|
|
interpolate_: function( i1, t0, t, t1 ) {
|
|
|
|
var result = this.resultBuffer,
|
|
values = this.sampleValues,
|
|
stride = this.valueSize,
|
|
|
|
o1 = i1 * stride, o0 = o1 - stride,
|
|
oP = this._offsetPrev, oN = this._offsetNext,
|
|
wP = this._weightPrev, wN = this._weightNext,
|
|
|
|
p = ( t - t0 ) / ( t1 - t0 ),
|
|
pp = p * p,
|
|
ppp = pp * p;
|
|
|
|
// evaluate polynomials
|
|
|
|
var sP = - wP * ppp + 2 * wP * pp - wP * p;
|
|
var s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;
|
|
var s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
|
|
var sN = wN * ppp - wN * pp;
|
|
|
|
// combine data linearly
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
result[ i ] =
|
|
sP * values[ oP + i ] +
|
|
s0 * values[ o0 + i ] +
|
|
s1 * values[ o1 + i ] +
|
|
sN * values[ oN + i ];
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author tschw
|
|
*/
|
|
|
|
function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
|
|
|
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
|
|
|
}
|
|
|
|
LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
|
|
|
constructor: LinearInterpolant,
|
|
|
|
interpolate_: function( i1, t0, t, t1 ) {
|
|
|
|
var result = this.resultBuffer,
|
|
values = this.sampleValues,
|
|
stride = this.valueSize,
|
|
|
|
offset1 = i1 * stride,
|
|
offset0 = offset1 - stride,
|
|
|
|
weight1 = ( t - t0 ) / ( t1 - t0 ),
|
|
weight0 = 1 - weight1;
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
result[ i ] =
|
|
values[ offset0 + i ] * weight0 +
|
|
values[ offset1 + i ] * weight1;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* Interpolant that evaluates to the sample value at the position preceeding
|
|
* the parameter.
|
|
*
|
|
* @author tschw
|
|
*/
|
|
|
|
function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
|
|
|
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
|
|
|
}
|
|
|
|
DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
|
|
|
constructor: DiscreteInterpolant,
|
|
|
|
interpolate_: function( i1, t0, t, t1 ) {
|
|
|
|
return this.copySampleValue_( i1 - 1 );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
var KeyframeTrackPrototype;
|
|
|
|
KeyframeTrackPrototype = {
|
|
|
|
TimeBufferType: Float32Array,
|
|
ValueBufferType: Float32Array,
|
|
|
|
DefaultInterpolation: InterpolateLinear,
|
|
|
|
InterpolantFactoryMethodDiscrete: function ( result ) {
|
|
|
|
return new DiscreteInterpolant(
|
|
this.times, this.values, this.getValueSize(), result );
|
|
|
|
},
|
|
|
|
InterpolantFactoryMethodLinear: function ( result ) {
|
|
|
|
return new LinearInterpolant(
|
|
this.times, this.values, this.getValueSize(), result );
|
|
|
|
},
|
|
|
|
InterpolantFactoryMethodSmooth: function ( result ) {
|
|
|
|
return new CubicInterpolant(
|
|
this.times, this.values, this.getValueSize(), result );
|
|
|
|
},
|
|
|
|
setInterpolation: function ( interpolation ) {
|
|
|
|
var factoryMethod;
|
|
|
|
switch ( interpolation ) {
|
|
|
|
case InterpolateDiscrete:
|
|
|
|
factoryMethod = this.InterpolantFactoryMethodDiscrete;
|
|
|
|
break;
|
|
|
|
case InterpolateLinear:
|
|
|
|
factoryMethod = this.InterpolantFactoryMethodLinear;
|
|
|
|
break;
|
|
|
|
case InterpolateSmooth:
|
|
|
|
factoryMethod = this.InterpolantFactoryMethodSmooth;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( factoryMethod === undefined ) {
|
|
|
|
var message = "unsupported interpolation for " +
|
|
this.ValueTypeName + " keyframe track named " + this.name;
|
|
|
|
if ( this.createInterpolant === undefined ) {
|
|
|
|
// fall back to default, unless the default itself is messed up
|
|
if ( interpolation !== this.DefaultInterpolation ) {
|
|
|
|
this.setInterpolation( this.DefaultInterpolation );
|
|
|
|
} else {
|
|
|
|
throw new Error( message ); // fatal, in this case
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.warn( message );
|
|
return;
|
|
|
|
}
|
|
|
|
this.createInterpolant = factoryMethod;
|
|
|
|
},
|
|
|
|
getInterpolation: function () {
|
|
|
|
switch ( this.createInterpolant ) {
|
|
|
|
case this.InterpolantFactoryMethodDiscrete:
|
|
|
|
return InterpolateDiscrete;
|
|
|
|
case this.InterpolantFactoryMethodLinear:
|
|
|
|
return InterpolateLinear;
|
|
|
|
case this.InterpolantFactoryMethodSmooth:
|
|
|
|
return InterpolateSmooth;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getValueSize: function () {
|
|
|
|
return this.values.length / this.times.length;
|
|
|
|
},
|
|
|
|
// move all keyframes either forwards or backwards in time
|
|
shift: function ( timeOffset ) {
|
|
|
|
if ( timeOffset !== 0.0 ) {
|
|
|
|
var times = this.times;
|
|
|
|
for ( var i = 0, n = times.length; i !== n; ++ i ) {
|
|
|
|
times[ i ] += timeOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// scale all keyframe times by a factor (useful for frame <-> seconds conversions)
|
|
scale: function ( timeScale ) {
|
|
|
|
if ( timeScale !== 1.0 ) {
|
|
|
|
var times = this.times;
|
|
|
|
for ( var i = 0, n = times.length; i !== n; ++ i ) {
|
|
|
|
times[ i ] *= timeScale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// removes keyframes before and after animation without changing any values within the range [startTime, endTime].
|
|
// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
|
|
trim: function ( startTime, endTime ) {
|
|
|
|
var times = this.times,
|
|
nKeys = times.length,
|
|
from = 0,
|
|
to = nKeys - 1;
|
|
|
|
while ( from !== nKeys && times[ from ] < startTime ) ++ from;
|
|
while ( to !== - 1 && times[ to ] > endTime ) -- to;
|
|
|
|
++ to; // inclusive -> exclusive bound
|
|
|
|
if ( from !== 0 || to !== nKeys ) {
|
|
|
|
// empty tracks are forbidden, so keep at least one keyframe
|
|
if ( from >= to ) to = Math.max( to, 1 ), from = to - 1;
|
|
|
|
var stride = this.getValueSize();
|
|
this.times = AnimationUtils.arraySlice( times, from, to );
|
|
this.values = AnimationUtils.
|
|
arraySlice( this.values, from * stride, to * stride );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
|
|
validate: function () {
|
|
|
|
var valid = true;
|
|
|
|
var valueSize = this.getValueSize();
|
|
if ( valueSize - Math.floor( valueSize ) !== 0 ) {
|
|
|
|
console.error( "invalid value size in track", this );
|
|
valid = false;
|
|
|
|
}
|
|
|
|
var times = this.times,
|
|
values = this.values,
|
|
|
|
nKeys = times.length;
|
|
|
|
if ( nKeys === 0 ) {
|
|
|
|
console.error( "track is empty", this );
|
|
valid = false;
|
|
|
|
}
|
|
|
|
var prevTime = null;
|
|
|
|
for ( var i = 0; i !== nKeys; i ++ ) {
|
|
|
|
var currTime = times[ i ];
|
|
|
|
if ( typeof currTime === 'number' && isNaN( currTime ) ) {
|
|
|
|
console.error( "time is not a valid number", this, i, currTime );
|
|
valid = false;
|
|
break;
|
|
|
|
}
|
|
|
|
if ( prevTime !== null && prevTime > currTime ) {
|
|
|
|
console.error( "out of order keys", this, i, currTime, prevTime );
|
|
valid = false;
|
|
break;
|
|
|
|
}
|
|
|
|
prevTime = currTime;
|
|
|
|
}
|
|
|
|
if ( values !== undefined ) {
|
|
|
|
if ( AnimationUtils.isTypedArray( values ) ) {
|
|
|
|
for ( var i = 0, n = values.length; i !== n; ++ i ) {
|
|
|
|
var value = values[ i ];
|
|
|
|
if ( isNaN( value ) ) {
|
|
|
|
console.error( "value is not a valid number", this, i, value );
|
|
valid = false;
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return valid;
|
|
|
|
},
|
|
|
|
// removes equivalent sequential keys as common in morph target sequences
|
|
// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
|
|
optimize: function () {
|
|
|
|
var times = this.times,
|
|
values = this.values,
|
|
stride = this.getValueSize(),
|
|
|
|
smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
|
|
|
|
writeIndex = 1,
|
|
lastIndex = times.length - 1;
|
|
|
|
for ( var i = 1; i < lastIndex; ++ i ) {
|
|
|
|
var keep = false;
|
|
|
|
var time = times[ i ];
|
|
var timeNext = times[ i + 1 ];
|
|
|
|
// remove adjacent keyframes scheduled at the same time
|
|
|
|
if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
|
|
|
|
if ( ! smoothInterpolation ) {
|
|
|
|
// remove unnecessary keyframes same as their neighbors
|
|
|
|
var offset = i * stride,
|
|
offsetP = offset - stride,
|
|
offsetN = offset + stride;
|
|
|
|
for ( var j = 0; j !== stride; ++ j ) {
|
|
|
|
var value = values[ offset + j ];
|
|
|
|
if ( value !== values[ offsetP + j ] ||
|
|
value !== values[ offsetN + j ] ) {
|
|
|
|
keep = true;
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else keep = true;
|
|
|
|
}
|
|
|
|
// in-place compaction
|
|
|
|
if ( keep ) {
|
|
|
|
if ( i !== writeIndex ) {
|
|
|
|
times[ writeIndex ] = times[ i ];
|
|
|
|
var readOffset = i * stride,
|
|
writeOffset = writeIndex * stride;
|
|
|
|
for ( var j = 0; j !== stride; ++ j )
|
|
|
|
values[ writeOffset + j ] = values[ readOffset + j ];
|
|
|
|
}
|
|
|
|
++ writeIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// flush last keyframe (compaction looks ahead)
|
|
|
|
if ( lastIndex > 0 ) {
|
|
|
|
times[ writeIndex ] = times[ lastIndex ];
|
|
|
|
for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )
|
|
|
|
values[ writeOffset + j ] = values[ readOffset + j ];
|
|
|
|
++ writeIndex;
|
|
|
|
}
|
|
|
|
if ( writeIndex !== times.length ) {
|
|
|
|
this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
|
|
this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
function KeyframeTrackConstructor( name, times, values, interpolation ) {
|
|
|
|
if ( name === undefined ) throw new Error( "track name is undefined" );
|
|
|
|
if ( times === undefined || times.length === 0 ) {
|
|
|
|
throw new Error( "no keyframes in track named " + name );
|
|
|
|
}
|
|
|
|
this.name = name;
|
|
|
|
this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
|
|
this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
|
|
|
|
this.setInterpolation( interpolation || this.DefaultInterpolation );
|
|
|
|
this.validate();
|
|
this.optimize();
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* A Track of vectored keyframe values.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function VectorKeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
|
|
|
|
}
|
|
|
|
VectorKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: VectorKeyframeTrack,
|
|
|
|
ValueTypeName: 'vector'
|
|
|
|
// ValueBufferType is inherited
|
|
|
|
// DefaultInterpolation is inherited
|
|
|
|
} );
|
|
|
|
/**
|
|
* Spherical linear unit quaternion interpolant.
|
|
*
|
|
* @author tschw
|
|
*/
|
|
|
|
function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
|
|
|
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
|
|
|
}
|
|
|
|
QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
|
|
|
constructor: QuaternionLinearInterpolant,
|
|
|
|
interpolate_: function( i1, t0, t, t1 ) {
|
|
|
|
var result = this.resultBuffer,
|
|
values = this.sampleValues,
|
|
stride = this.valueSize,
|
|
|
|
offset = i1 * stride,
|
|
|
|
alpha = ( t - t0 ) / ( t1 - t0 );
|
|
|
|
for ( var end = offset + stride; offset !== end; offset += 4 ) {
|
|
|
|
Quaternion.slerpFlat( result, 0,
|
|
values, offset - stride, values, offset, alpha );
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A Track of quaternion keyframe values.
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function QuaternionKeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
|
|
|
|
}
|
|
|
|
QuaternionKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: QuaternionKeyframeTrack,
|
|
|
|
ValueTypeName: 'quaternion',
|
|
|
|
// ValueBufferType is inherited
|
|
|
|
DefaultInterpolation: InterpolateLinear,
|
|
|
|
InterpolantFactoryMethodLinear: function( result ) {
|
|
|
|
return new QuaternionLinearInterpolant(
|
|
this.times, this.values, this.getValueSize(), result );
|
|
|
|
},
|
|
|
|
InterpolantFactoryMethodSmooth: undefined // not yet implemented
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A Track of numeric keyframe values.
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function NumberKeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
|
|
|
|
}
|
|
|
|
NumberKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: NumberKeyframeTrack,
|
|
|
|
ValueTypeName: 'number'
|
|
|
|
// ValueBufferType is inherited
|
|
|
|
// DefaultInterpolation is inherited
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A Track that interpolates Strings
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function StringKeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
|
|
|
|
}
|
|
|
|
StringKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: StringKeyframeTrack,
|
|
|
|
ValueTypeName: 'string',
|
|
ValueBufferType: Array,
|
|
|
|
DefaultInterpolation: InterpolateDiscrete,
|
|
|
|
InterpolantFactoryMethodLinear: undefined,
|
|
|
|
InterpolantFactoryMethodSmooth: undefined
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A Track of Boolean keyframe values.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function BooleanKeyframeTrack( name, times, values ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values );
|
|
|
|
}
|
|
|
|
BooleanKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: BooleanKeyframeTrack,
|
|
|
|
ValueTypeName: 'bool',
|
|
ValueBufferType: Array,
|
|
|
|
DefaultInterpolation: InterpolateDiscrete,
|
|
|
|
InterpolantFactoryMethodLinear: undefined,
|
|
InterpolantFactoryMethodSmooth: undefined
|
|
|
|
// Note: Actually this track could have a optimized / compressed
|
|
// representation of a single value and a custom interpolant that
|
|
// computes "firstValue ^ isOdd( index )".
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A Track of keyframe values that represent color.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function ColorKeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
|
|
|
|
}
|
|
|
|
ColorKeyframeTrack.prototype =
|
|
Object.assign( Object.create( KeyframeTrackPrototype ), {
|
|
|
|
constructor: ColorKeyframeTrack,
|
|
|
|
ValueTypeName: 'color'
|
|
|
|
// ValueBufferType is inherited
|
|
|
|
// DefaultInterpolation is inherited
|
|
|
|
|
|
// Note: Very basic implementation and nothing special yet.
|
|
// However, this is the place for color space parameterization.
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A timed sequence of keyframes for a specific property.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function KeyframeTrack( name, times, values, interpolation ) {
|
|
|
|
KeyframeTrackConstructor.apply( this, arguments );
|
|
|
|
}
|
|
|
|
KeyframeTrack.prototype = KeyframeTrackPrototype;
|
|
KeyframeTrackPrototype.constructor = KeyframeTrack;
|
|
|
|
// Static methods:
|
|
|
|
Object.assign( KeyframeTrack, {
|
|
|
|
// Serialization (in static context, because of constructor invocation
|
|
// and automatic invocation of .toJSON):
|
|
|
|
parse: function( json ) {
|
|
|
|
if( json.type === undefined ) {
|
|
|
|
throw new Error( "track type undefined, can not parse" );
|
|
|
|
}
|
|
|
|
var trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );
|
|
|
|
if ( json.times === undefined ) {
|
|
|
|
var times = [], values = [];
|
|
|
|
AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
|
|
|
|
json.times = times;
|
|
json.values = values;
|
|
|
|
}
|
|
|
|
// derived classes can define a static parse method
|
|
if ( trackType.parse !== undefined ) {
|
|
|
|
return trackType.parse( json );
|
|
|
|
} else {
|
|
|
|
// by default, we asssume a constructor compatible with the base
|
|
return new trackType(
|
|
json.name, json.times, json.values, json.interpolation );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toJSON: function( track ) {
|
|
|
|
var trackType = track.constructor;
|
|
|
|
var json;
|
|
|
|
// derived classes can define a static toJSON method
|
|
if ( trackType.toJSON !== undefined ) {
|
|
|
|
json = trackType.toJSON( track );
|
|
|
|
} else {
|
|
|
|
// by default, we assume the data can be serialized as-is
|
|
json = {
|
|
|
|
'name': track.name,
|
|
'times': AnimationUtils.convertArray( track.times, Array ),
|
|
'values': AnimationUtils.convertArray( track.values, Array )
|
|
|
|
};
|
|
|
|
var interpolation = track.getInterpolation();
|
|
|
|
if ( interpolation !== track.DefaultInterpolation ) {
|
|
|
|
json.interpolation = interpolation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
json.type = track.ValueTypeName; // mandatory
|
|
|
|
return json;
|
|
|
|
},
|
|
|
|
_getTrackTypeForValueTypeName: function( typeName ) {
|
|
|
|
switch( typeName.toLowerCase() ) {
|
|
|
|
case "scalar":
|
|
case "double":
|
|
case "float":
|
|
case "number":
|
|
case "integer":
|
|
|
|
return NumberKeyframeTrack;
|
|
|
|
case "vector":
|
|
case "vector2":
|
|
case "vector3":
|
|
case "vector4":
|
|
|
|
return VectorKeyframeTrack;
|
|
|
|
case "color":
|
|
|
|
return ColorKeyframeTrack;
|
|
|
|
case "quaternion":
|
|
|
|
return QuaternionKeyframeTrack;
|
|
|
|
case "bool":
|
|
case "boolean":
|
|
|
|
return BooleanKeyframeTrack;
|
|
|
|
case "string":
|
|
|
|
return StringKeyframeTrack;
|
|
|
|
}
|
|
|
|
throw new Error( "Unsupported typeName: " + typeName );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* Reusable set of Tracks that represent an animation.
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
*/
|
|
|
|
function AnimationClip( name, duration, tracks ) {
|
|
|
|
this.name = name;
|
|
this.tracks = tracks;
|
|
this.duration = ( duration !== undefined ) ? duration : - 1;
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
// this means it should figure out its duration by scanning the tracks
|
|
if ( this.duration < 0 ) {
|
|
|
|
this.resetDuration();
|
|
|
|
}
|
|
|
|
this.optimize();
|
|
|
|
}
|
|
|
|
Object.assign( AnimationClip, {
|
|
|
|
parse: function ( json ) {
|
|
|
|
var tracks = [],
|
|
jsonTracks = json.tracks,
|
|
frameTime = 1.0 / ( json.fps || 1.0 );
|
|
|
|
for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {
|
|
|
|
tracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );
|
|
|
|
}
|
|
|
|
return new AnimationClip( json.name, json.duration, tracks );
|
|
|
|
},
|
|
|
|
toJSON: function ( clip ) {
|
|
|
|
var tracks = [],
|
|
clipTracks = clip.tracks;
|
|
|
|
var json = {
|
|
|
|
'name': clip.name,
|
|
'duration': clip.duration,
|
|
'tracks': tracks
|
|
|
|
};
|
|
|
|
for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {
|
|
|
|
tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
|
|
|
|
}
|
|
|
|
return json;
|
|
|
|
},
|
|
|
|
CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
|
|
|
|
var numMorphTargets = morphTargetSequence.length;
|
|
var tracks = [];
|
|
|
|
for ( var i = 0; i < numMorphTargets; i ++ ) {
|
|
|
|
var times = [];
|
|
var values = [];
|
|
|
|
times.push(
|
|
( i + numMorphTargets - 1 ) % numMorphTargets,
|
|
i,
|
|
( i + 1 ) % numMorphTargets );
|
|
|
|
values.push( 0, 1, 0 );
|
|
|
|
var order = AnimationUtils.getKeyframeOrder( times );
|
|
times = AnimationUtils.sortedArray( times, 1, order );
|
|
values = AnimationUtils.sortedArray( values, 1, order );
|
|
|
|
// if there is a key at the first frame, duplicate it as the
|
|
// last frame as well for perfect loop.
|
|
if ( ! noLoop && times[ 0 ] === 0 ) {
|
|
|
|
times.push( numMorphTargets );
|
|
values.push( values[ 0 ] );
|
|
|
|
}
|
|
|
|
tracks.push(
|
|
new NumberKeyframeTrack(
|
|
'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
|
|
times, values
|
|
).scale( 1.0 / fps ) );
|
|
|
|
}
|
|
|
|
return new AnimationClip( name, - 1, tracks );
|
|
|
|
},
|
|
|
|
findByName: function ( objectOrClipArray, name ) {
|
|
|
|
var clipArray = objectOrClipArray;
|
|
|
|
if ( ! Array.isArray( objectOrClipArray ) ) {
|
|
|
|
var o = objectOrClipArray;
|
|
clipArray = o.geometry && o.geometry.animations || o.animations;
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < clipArray.length; i ++ ) {
|
|
|
|
if ( clipArray[ i ].name === name ) {
|
|
|
|
return clipArray[ i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
|
|
|
|
var animationToMorphTargets = {};
|
|
|
|
// tested with https://regex101.com/ on trick sequences
|
|
// such flamingo_flyA_003, flamingo_run1_003, crdeath0059
|
|
var pattern = /^([\w-]*?)([\d]+)$/;
|
|
|
|
// sort morph target names into animation groups based
|
|
// patterns like Walk_001, Walk_002, Run_001, Run_002
|
|
for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
|
|
|
|
var morphTarget = morphTargets[ i ];
|
|
var parts = morphTarget.name.match( pattern );
|
|
|
|
if ( parts && parts.length > 1 ) {
|
|
|
|
var name = parts[ 1 ];
|
|
|
|
var animationMorphTargets = animationToMorphTargets[ name ];
|
|
if ( ! animationMorphTargets ) {
|
|
|
|
animationToMorphTargets[ name ] = animationMorphTargets = [];
|
|
|
|
}
|
|
|
|
animationMorphTargets.push( morphTarget );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var clips = [];
|
|
|
|
for ( var name in animationToMorphTargets ) {
|
|
|
|
clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
|
|
|
|
}
|
|
|
|
return clips;
|
|
|
|
},
|
|
|
|
// parse the animation.hierarchy format
|
|
parseAnimation: function ( animation, bones ) {
|
|
|
|
if ( ! animation ) {
|
|
|
|
console.error( " no animation in JSONLoader data" );
|
|
return null;
|
|
|
|
}
|
|
|
|
var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
|
|
|
|
// only return track if there are actually keys.
|
|
if ( animationKeys.length !== 0 ) {
|
|
|
|
var times = [];
|
|
var values = [];
|
|
|
|
AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
|
|
|
|
// empty keys are filtered out, so check again
|
|
if ( times.length !== 0 ) {
|
|
|
|
destTracks.push( new trackType( trackName, times, values ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var tracks = [];
|
|
|
|
var clipName = animation.name || 'default';
|
|
// automatic length determination in AnimationClip.
|
|
var duration = animation.length || - 1;
|
|
var fps = animation.fps || 30;
|
|
|
|
var hierarchyTracks = animation.hierarchy || [];
|
|
|
|
for ( var h = 0; h < hierarchyTracks.length; h ++ ) {
|
|
|
|
var animationKeys = hierarchyTracks[ h ].keys;
|
|
|
|
// skip empty tracks
|
|
if ( ! animationKeys || animationKeys.length === 0 ) continue;
|
|
|
|
// process morph targets in a way exactly compatible
|
|
// with AnimationHandler.init( animation )
|
|
if ( animationKeys[ 0 ].morphTargets ) {
|
|
|
|
// figure out all morph targets used in this track
|
|
var morphTargetNames = {};
|
|
|
|
for ( var k = 0; k < animationKeys.length; k ++ ) {
|
|
|
|
if ( animationKeys[ k ].morphTargets ) {
|
|
|
|
for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
|
|
|
|
morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// create a track for each morph target with all zero
|
|
// morphTargetInfluences except for the keys in which
|
|
// the morphTarget is named.
|
|
for ( var morphTargetName in morphTargetNames ) {
|
|
|
|
var times = [];
|
|
var values = [];
|
|
|
|
for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {
|
|
|
|
var animationKey = animationKeys[ k ];
|
|
|
|
times.push( animationKey.time );
|
|
values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
|
|
|
|
}
|
|
|
|
tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
|
|
|
|
}
|
|
|
|
duration = morphTargetNames.length * ( fps || 1.0 );
|
|
|
|
} else {
|
|
|
|
// ...assume skeletal animation
|
|
|
|
var boneName = '.bones[' + bones[ h ].name + ']';
|
|
|
|
addNonemptyTrack(
|
|
VectorKeyframeTrack, boneName + '.position',
|
|
animationKeys, 'pos', tracks );
|
|
|
|
addNonemptyTrack(
|
|
QuaternionKeyframeTrack, boneName + '.quaternion',
|
|
animationKeys, 'rot', tracks );
|
|
|
|
addNonemptyTrack(
|
|
VectorKeyframeTrack, boneName + '.scale',
|
|
animationKeys, 'scl', tracks );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( tracks.length === 0 ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var clip = new AnimationClip( clipName, duration, tracks );
|
|
|
|
return clip;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( AnimationClip.prototype, {
|
|
|
|
resetDuration: function () {
|
|
|
|
var tracks = this.tracks, duration = 0;
|
|
|
|
for ( var i = 0, n = tracks.length; i !== n; ++ i ) {
|
|
|
|
var track = this.tracks[ i ];
|
|
|
|
duration = Math.max( duration, track.times[ track.times.length - 1 ] );
|
|
|
|
}
|
|
|
|
this.duration = duration;
|
|
|
|
},
|
|
|
|
trim: function () {
|
|
|
|
for ( var i = 0; i < this.tracks.length; i ++ ) {
|
|
|
|
this.tracks[ i ].trim( 0, this.duration );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
optimize: function () {
|
|
|
|
for ( var i = 0; i < this.tracks.length; i ++ ) {
|
|
|
|
this.tracks[ i ].optimize();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function MaterialLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
this.textures = {};
|
|
|
|
}
|
|
|
|
Object.assign( MaterialLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var loader = new FileLoader( scope.manager );
|
|
loader.setResponseType( 'json' );
|
|
loader.load( url, function ( json ) {
|
|
|
|
onLoad( scope.parse( json ) );
|
|
|
|
}, onProgress, onError );
|
|
|
|
},
|
|
|
|
setTextures: function ( value ) {
|
|
|
|
this.textures = value;
|
|
|
|
},
|
|
|
|
parse: function ( json ) {
|
|
|
|
var textures = this.textures;
|
|
|
|
function getTexture( name ) {
|
|
|
|
if ( textures[ name ] === undefined ) {
|
|
|
|
console.warn( 'THREE.MaterialLoader: Undefined texture', name );
|
|
|
|
}
|
|
|
|
return textures[ name ];
|
|
|
|
}
|
|
|
|
var material = new Materials[ json.type ]();
|
|
|
|
if ( json.uuid !== undefined ) material.uuid = json.uuid;
|
|
if ( json.name !== undefined ) material.name = json.name;
|
|
if ( json.color !== undefined ) material.color.setHex( json.color );
|
|
if ( json.roughness !== undefined ) material.roughness = json.roughness;
|
|
if ( json.metalness !== undefined ) material.metalness = json.metalness;
|
|
if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
|
|
if ( json.specular !== undefined ) material.specular.setHex( json.specular );
|
|
if ( json.shininess !== undefined ) material.shininess = json.shininess;
|
|
if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;
|
|
if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;
|
|
if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
|
|
if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
|
|
if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
|
|
if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
|
|
if ( json.fog !== undefined ) material.fog = json.fog;
|
|
if ( json.shading !== undefined ) material.shading = json.shading;
|
|
if ( json.blending !== undefined ) material.blending = json.blending;
|
|
if ( json.side !== undefined ) material.side = json.side;
|
|
if ( json.opacity !== undefined ) material.opacity = json.opacity;
|
|
if ( json.transparent !== undefined ) material.transparent = json.transparent;
|
|
if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
|
|
if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
|
|
if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
|
|
if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
|
|
if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
|
|
if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
|
|
if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
|
|
if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
|
|
if ( json.skinning !== undefined ) material.skinning = json.skinning;
|
|
if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;
|
|
|
|
// for PointsMaterial
|
|
|
|
if ( json.size !== undefined ) material.size = json.size;
|
|
if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;
|
|
|
|
// maps
|
|
|
|
if ( json.map !== undefined ) material.map = getTexture( json.map );
|
|
|
|
if ( json.alphaMap !== undefined ) {
|
|
|
|
material.alphaMap = getTexture( json.alphaMap );
|
|
material.transparent = true;
|
|
|
|
}
|
|
|
|
if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
|
|
if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;
|
|
|
|
if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
|
|
if ( json.normalScale !== undefined ) {
|
|
|
|
var normalScale = json.normalScale;
|
|
|
|
if ( Array.isArray( normalScale ) === false ) {
|
|
|
|
// Blender exporter used to export a scalar. See #7459
|
|
|
|
normalScale = [ normalScale, normalScale ];
|
|
|
|
}
|
|
|
|
material.normalScale = new Vector2().fromArray( normalScale );
|
|
|
|
}
|
|
|
|
if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
|
|
if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
|
|
if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;
|
|
|
|
if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
|
|
if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );
|
|
|
|
if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
|
|
if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;
|
|
|
|
if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );
|
|
|
|
if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );
|
|
|
|
if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;
|
|
|
|
if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
|
|
if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;
|
|
|
|
if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
|
|
if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;
|
|
|
|
if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );
|
|
|
|
return material;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function BufferGeometryLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( BufferGeometryLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var loader = new FileLoader( scope.manager );
|
|
loader.setResponseType( 'json' );
|
|
loader.load( url, function ( json ) {
|
|
|
|
onLoad( scope.parse( json ) );
|
|
|
|
}, onProgress, onError );
|
|
|
|
},
|
|
|
|
parse: function ( json ) {
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
var index = json.data.index;
|
|
|
|
if ( index !== undefined ) {
|
|
|
|
var typedArray = new TYPED_ARRAYS[ index.type ]( index.array );
|
|
geometry.setIndex( new BufferAttribute( typedArray, 1 ) );
|
|
|
|
}
|
|
|
|
var attributes = json.data.attributes;
|
|
|
|
for ( var key in attributes ) {
|
|
|
|
var attribute = attributes[ key ];
|
|
var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
|
|
|
|
geometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );
|
|
|
|
}
|
|
|
|
var groups = json.data.groups || json.data.drawcalls || json.data.offsets;
|
|
|
|
if ( groups !== undefined ) {
|
|
|
|
for ( var i = 0, n = groups.length; i !== n; ++ i ) {
|
|
|
|
var group = groups[ i ];
|
|
|
|
geometry.addGroup( group.start, group.count, group.materialIndex );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var boundingSphere = json.data.boundingSphere;
|
|
|
|
if ( boundingSphere !== undefined ) {
|
|
|
|
var center = new Vector3();
|
|
|
|
if ( boundingSphere.center !== undefined ) {
|
|
|
|
center.fromArray( boundingSphere.center );
|
|
|
|
}
|
|
|
|
geometry.boundingSphere = new Sphere( center, boundingSphere.radius );
|
|
|
|
}
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
var TYPED_ARRAYS = {
|
|
Int8Array: Int8Array,
|
|
Uint8Array: Uint8Array,
|
|
Uint8ClampedArray: Uint8ClampedArray,
|
|
Int16Array: Int16Array,
|
|
Uint16Array: Uint16Array,
|
|
Int32Array: Int32Array,
|
|
Uint32Array: Uint32Array,
|
|
Float32Array: Float32Array,
|
|
Float64Array: Float64Array
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Loader() {
|
|
|
|
this.onLoadStart = function () {};
|
|
this.onLoadProgress = function () {};
|
|
this.onLoadComplete = function () {};
|
|
|
|
}
|
|
|
|
Loader.Handlers = {
|
|
|
|
handlers: [],
|
|
|
|
add: function ( regex, loader ) {
|
|
|
|
this.handlers.push( regex, loader );
|
|
|
|
},
|
|
|
|
get: function ( file ) {
|
|
|
|
var handlers = this.handlers;
|
|
|
|
for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
|
|
|
|
var regex = handlers[ i ];
|
|
var loader = handlers[ i + 1 ];
|
|
|
|
if ( regex.test( file ) ) {
|
|
|
|
return loader;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Object.assign( Loader.prototype, {
|
|
|
|
crossOrigin: undefined,
|
|
|
|
extractUrlBase: function ( url ) {
|
|
|
|
var parts = url.split( '/' );
|
|
|
|
if ( parts.length === 1 ) return './';
|
|
|
|
parts.pop();
|
|
|
|
return parts.join( '/' ) + '/';
|
|
|
|
},
|
|
|
|
initMaterials: function ( materials, texturePath, crossOrigin ) {
|
|
|
|
var array = [];
|
|
|
|
for ( var i = 0; i < materials.length; ++ i ) {
|
|
|
|
array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
},
|
|
|
|
createMaterial: ( function () {
|
|
|
|
var BlendingMode = {
|
|
NoBlending: NoBlending,
|
|
NormalBlending: NormalBlending,
|
|
AdditiveBlending: AdditiveBlending,
|
|
SubtractiveBlending: SubtractiveBlending,
|
|
MultiplyBlending: MultiplyBlending,
|
|
CustomBlending: CustomBlending
|
|
};
|
|
|
|
var color = new Color();
|
|
var textureLoader = new TextureLoader();
|
|
var materialLoader = new MaterialLoader();
|
|
|
|
return function createMaterial( m, texturePath, crossOrigin ) {
|
|
|
|
// convert from old material format
|
|
|
|
var textures = {};
|
|
|
|
function loadTexture( path, repeat, offset, wrap, anisotropy ) {
|
|
|
|
var fullPath = texturePath + path;
|
|
var loader = Loader.Handlers.get( fullPath );
|
|
|
|
var texture;
|
|
|
|
if ( loader !== null ) {
|
|
|
|
texture = loader.load( fullPath );
|
|
|
|
} else {
|
|
|
|
textureLoader.setCrossOrigin( crossOrigin );
|
|
texture = textureLoader.load( fullPath );
|
|
|
|
}
|
|
|
|
if ( repeat !== undefined ) {
|
|
|
|
texture.repeat.fromArray( repeat );
|
|
|
|
if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;
|
|
if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;
|
|
|
|
}
|
|
|
|
if ( offset !== undefined ) {
|
|
|
|
texture.offset.fromArray( offset );
|
|
|
|
}
|
|
|
|
if ( wrap !== undefined ) {
|
|
|
|
if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;
|
|
if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;
|
|
|
|
if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;
|
|
if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;
|
|
|
|
}
|
|
|
|
if ( anisotropy !== undefined ) {
|
|
|
|
texture.anisotropy = anisotropy;
|
|
|
|
}
|
|
|
|
var uuid = _Math.generateUUID();
|
|
|
|
textures[ uuid ] = texture;
|
|
|
|
return uuid;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var json = {
|
|
uuid: _Math.generateUUID(),
|
|
type: 'MeshLambertMaterial'
|
|
};
|
|
|
|
for ( var name in m ) {
|
|
|
|
var value = m[ name ];
|
|
|
|
switch ( name ) {
|
|
|
|
case 'DbgColor':
|
|
case 'DbgIndex':
|
|
case 'opticalDensity':
|
|
case 'illumination':
|
|
break;
|
|
case 'DbgName':
|
|
json.name = value;
|
|
break;
|
|
case 'blending':
|
|
json.blending = BlendingMode[ value ];
|
|
break;
|
|
case 'colorAmbient':
|
|
case 'mapAmbient':
|
|
console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );
|
|
break;
|
|
case 'colorDiffuse':
|
|
json.color = color.fromArray( value ).getHex();
|
|
break;
|
|
case 'colorSpecular':
|
|
json.specular = color.fromArray( value ).getHex();
|
|
break;
|
|
case 'colorEmissive':
|
|
json.emissive = color.fromArray( value ).getHex();
|
|
break;
|
|
case 'specularCoef':
|
|
json.shininess = value;
|
|
break;
|
|
case 'shading':
|
|
if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
|
|
if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
|
|
if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';
|
|
break;
|
|
case 'mapDiffuse':
|
|
json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
|
|
break;
|
|
case 'mapDiffuseRepeat':
|
|
case 'mapDiffuseOffset':
|
|
case 'mapDiffuseWrap':
|
|
case 'mapDiffuseAnisotropy':
|
|
break;
|
|
case 'mapEmissive':
|
|
json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );
|
|
break;
|
|
case 'mapEmissiveRepeat':
|
|
case 'mapEmissiveOffset':
|
|
case 'mapEmissiveWrap':
|
|
case 'mapEmissiveAnisotropy':
|
|
break;
|
|
case 'mapLight':
|
|
json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
|
|
break;
|
|
case 'mapLightRepeat':
|
|
case 'mapLightOffset':
|
|
case 'mapLightWrap':
|
|
case 'mapLightAnisotropy':
|
|
break;
|
|
case 'mapAO':
|
|
json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
|
|
break;
|
|
case 'mapAORepeat':
|
|
case 'mapAOOffset':
|
|
case 'mapAOWrap':
|
|
case 'mapAOAnisotropy':
|
|
break;
|
|
case 'mapBump':
|
|
json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
|
|
break;
|
|
case 'mapBumpScale':
|
|
json.bumpScale = value;
|
|
break;
|
|
case 'mapBumpRepeat':
|
|
case 'mapBumpOffset':
|
|
case 'mapBumpWrap':
|
|
case 'mapBumpAnisotropy':
|
|
break;
|
|
case 'mapNormal':
|
|
json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
|
|
break;
|
|
case 'mapNormalFactor':
|
|
json.normalScale = [ value, value ];
|
|
break;
|
|
case 'mapNormalRepeat':
|
|
case 'mapNormalOffset':
|
|
case 'mapNormalWrap':
|
|
case 'mapNormalAnisotropy':
|
|
break;
|
|
case 'mapSpecular':
|
|
json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
|
|
break;
|
|
case 'mapSpecularRepeat':
|
|
case 'mapSpecularOffset':
|
|
case 'mapSpecularWrap':
|
|
case 'mapSpecularAnisotropy':
|
|
break;
|
|
case 'mapMetalness':
|
|
json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );
|
|
break;
|
|
case 'mapMetalnessRepeat':
|
|
case 'mapMetalnessOffset':
|
|
case 'mapMetalnessWrap':
|
|
case 'mapMetalnessAnisotropy':
|
|
break;
|
|
case 'mapRoughness':
|
|
json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );
|
|
break;
|
|
case 'mapRoughnessRepeat':
|
|
case 'mapRoughnessOffset':
|
|
case 'mapRoughnessWrap':
|
|
case 'mapRoughnessAnisotropy':
|
|
break;
|
|
case 'mapAlpha':
|
|
json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
|
|
break;
|
|
case 'mapAlphaRepeat':
|
|
case 'mapAlphaOffset':
|
|
case 'mapAlphaWrap':
|
|
case 'mapAlphaAnisotropy':
|
|
break;
|
|
case 'flipSided':
|
|
json.side = BackSide;
|
|
break;
|
|
case 'doubleSided':
|
|
json.side = DoubleSide;
|
|
break;
|
|
case 'transparency':
|
|
console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );
|
|
json.opacity = value;
|
|
break;
|
|
case 'depthTest':
|
|
case 'depthWrite':
|
|
case 'colorWrite':
|
|
case 'opacity':
|
|
case 'reflectivity':
|
|
case 'transparent':
|
|
case 'visible':
|
|
case 'wireframe':
|
|
json[ name ] = value;
|
|
break;
|
|
case 'vertexColors':
|
|
if ( value === true ) json.vertexColors = VertexColors;
|
|
if ( value === 'face' ) json.vertexColors = FaceColors;
|
|
break;
|
|
default:
|
|
console.error( 'THREE.Loader.createMaterial: Unsupported', name, value );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( json.type === 'MeshBasicMaterial' ) delete json.emissive;
|
|
if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
|
|
|
|
if ( json.opacity < 1 ) json.transparent = true;
|
|
|
|
materialLoader.setTextures( textures );
|
|
|
|
return materialLoader.parse( json );
|
|
|
|
};
|
|
|
|
} )()
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function JSONLoader( manager ) {
|
|
|
|
if ( typeof manager === 'boolean' ) {
|
|
|
|
console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
|
|
manager = undefined;
|
|
|
|
}
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
this.withCredentials = false;
|
|
|
|
}
|
|
|
|
Object.assign( JSONLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );
|
|
|
|
var loader = new FileLoader( this.manager );
|
|
loader.setResponseType( 'json' );
|
|
loader.setWithCredentials( this.withCredentials );
|
|
loader.load( url, function ( json ) {
|
|
|
|
var metadata = json.metadata;
|
|
|
|
if ( metadata !== undefined ) {
|
|
|
|
var type = metadata.type;
|
|
|
|
if ( type !== undefined ) {
|
|
|
|
if ( type.toLowerCase() === 'object' ) {
|
|
|
|
console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( type.toLowerCase() === 'scene' ) {
|
|
|
|
console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var object = scope.parse( json, texturePath );
|
|
onLoad( object.geometry, object.materials );
|
|
|
|
}, onProgress, onError );
|
|
|
|
},
|
|
|
|
setTexturePath: function ( value ) {
|
|
|
|
this.texturePath = value;
|
|
|
|
},
|
|
|
|
parse: ( function () {
|
|
|
|
function parseModel( json, geometry ) {
|
|
|
|
function isBitSet( value, position ) {
|
|
|
|
return value & ( 1 << position );
|
|
|
|
}
|
|
|
|
var i, j, fi,
|
|
|
|
offset, zLength,
|
|
|
|
colorIndex, normalIndex, uvIndex, materialIndex,
|
|
|
|
type,
|
|
isQuad,
|
|
hasMaterial,
|
|
hasFaceVertexUv,
|
|
hasFaceNormal, hasFaceVertexNormal,
|
|
hasFaceColor, hasFaceVertexColor,
|
|
|
|
vertex, face, faceA, faceB, hex, normal,
|
|
|
|
uvLayer, uv, u, v,
|
|
|
|
faces = json.faces,
|
|
vertices = json.vertices,
|
|
normals = json.normals,
|
|
colors = json.colors,
|
|
|
|
scale = json.scale,
|
|
|
|
nUvLayers = 0;
|
|
|
|
|
|
if ( json.uvs !== undefined ) {
|
|
|
|
// disregard empty arrays
|
|
|
|
for ( i = 0; i < json.uvs.length; i ++ ) {
|
|
|
|
if ( json.uvs[ i ].length ) nUvLayers ++;
|
|
|
|
}
|
|
|
|
for ( i = 0; i < nUvLayers; i ++ ) {
|
|
|
|
geometry.faceVertexUvs[ i ] = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
zLength = vertices.length;
|
|
|
|
while ( offset < zLength ) {
|
|
|
|
vertex = new Vector3();
|
|
|
|
vertex.x = vertices[ offset ++ ] * scale;
|
|
vertex.y = vertices[ offset ++ ] * scale;
|
|
vertex.z = vertices[ offset ++ ] * scale;
|
|
|
|
geometry.vertices.push( vertex );
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
zLength = faces.length;
|
|
|
|
while ( offset < zLength ) {
|
|
|
|
type = faces[ offset ++ ];
|
|
|
|
isQuad = isBitSet( type, 0 );
|
|
hasMaterial = isBitSet( type, 1 );
|
|
hasFaceVertexUv = isBitSet( type, 3 );
|
|
hasFaceNormal = isBitSet( type, 4 );
|
|
hasFaceVertexNormal = isBitSet( type, 5 );
|
|
hasFaceColor = isBitSet( type, 6 );
|
|
hasFaceVertexColor = isBitSet( type, 7 );
|
|
|
|
// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
|
|
|
|
if ( isQuad ) {
|
|
|
|
faceA = new Face3();
|
|
faceA.a = faces[ offset ];
|
|
faceA.b = faces[ offset + 1 ];
|
|
faceA.c = faces[ offset + 3 ];
|
|
|
|
faceB = new Face3();
|
|
faceB.a = faces[ offset + 1 ];
|
|
faceB.b = faces[ offset + 2 ];
|
|
faceB.c = faces[ offset + 3 ];
|
|
|
|
offset += 4;
|
|
|
|
if ( hasMaterial ) {
|
|
|
|
materialIndex = faces[ offset ++ ];
|
|
faceA.materialIndex = materialIndex;
|
|
faceB.materialIndex = materialIndex;
|
|
|
|
}
|
|
|
|
// to get face <=> uv index correspondence
|
|
|
|
fi = geometry.faces.length;
|
|
|
|
if ( hasFaceVertexUv ) {
|
|
|
|
for ( i = 0; i < nUvLayers; i ++ ) {
|
|
|
|
uvLayer = json.uvs[ i ];
|
|
|
|
geometry.faceVertexUvs[ i ][ fi ] = [];
|
|
geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
|
|
|
|
for ( j = 0; j < 4; j ++ ) {
|
|
|
|
uvIndex = faces[ offset ++ ];
|
|
|
|
u = uvLayer[ uvIndex * 2 ];
|
|
v = uvLayer[ uvIndex * 2 + 1 ];
|
|
|
|
uv = new Vector2( u, v );
|
|
|
|
if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
|
|
if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( hasFaceNormal ) {
|
|
|
|
normalIndex = faces[ offset ++ ] * 3;
|
|
|
|
faceA.normal.set(
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ]
|
|
);
|
|
|
|
faceB.normal.copy( faceA.normal );
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexNormal ) {
|
|
|
|
for ( i = 0; i < 4; i ++ ) {
|
|
|
|
normalIndex = faces[ offset ++ ] * 3;
|
|
|
|
normal = new Vector3(
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ]
|
|
);
|
|
|
|
|
|
if ( i !== 2 ) faceA.vertexNormals.push( normal );
|
|
if ( i !== 0 ) faceB.vertexNormals.push( normal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if ( hasFaceColor ) {
|
|
|
|
colorIndex = faces[ offset ++ ];
|
|
hex = colors[ colorIndex ];
|
|
|
|
faceA.color.setHex( hex );
|
|
faceB.color.setHex( hex );
|
|
|
|
}
|
|
|
|
|
|
if ( hasFaceVertexColor ) {
|
|
|
|
for ( i = 0; i < 4; i ++ ) {
|
|
|
|
colorIndex = faces[ offset ++ ];
|
|
hex = colors[ colorIndex ];
|
|
|
|
if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );
|
|
if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.faces.push( faceA );
|
|
geometry.faces.push( faceB );
|
|
|
|
} else {
|
|
|
|
face = new Face3();
|
|
face.a = faces[ offset ++ ];
|
|
face.b = faces[ offset ++ ];
|
|
face.c = faces[ offset ++ ];
|
|
|
|
if ( hasMaterial ) {
|
|
|
|
materialIndex = faces[ offset ++ ];
|
|
face.materialIndex = materialIndex;
|
|
|
|
}
|
|
|
|
// to get face <=> uv index correspondence
|
|
|
|
fi = geometry.faces.length;
|
|
|
|
if ( hasFaceVertexUv ) {
|
|
|
|
for ( i = 0; i < nUvLayers; i ++ ) {
|
|
|
|
uvLayer = json.uvs[ i ];
|
|
|
|
geometry.faceVertexUvs[ i ][ fi ] = [];
|
|
|
|
for ( j = 0; j < 3; j ++ ) {
|
|
|
|
uvIndex = faces[ offset ++ ];
|
|
|
|
u = uvLayer[ uvIndex * 2 ];
|
|
v = uvLayer[ uvIndex * 2 + 1 ];
|
|
|
|
uv = new Vector2( u, v );
|
|
|
|
geometry.faceVertexUvs[ i ][ fi ].push( uv );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( hasFaceNormal ) {
|
|
|
|
normalIndex = faces[ offset ++ ] * 3;
|
|
|
|
face.normal.set(
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ]
|
|
);
|
|
|
|
}
|
|
|
|
if ( hasFaceVertexNormal ) {
|
|
|
|
for ( i = 0; i < 3; i ++ ) {
|
|
|
|
normalIndex = faces[ offset ++ ] * 3;
|
|
|
|
normal = new Vector3(
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ++ ],
|
|
normals[ normalIndex ]
|
|
);
|
|
|
|
face.vertexNormals.push( normal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if ( hasFaceColor ) {
|
|
|
|
colorIndex = faces[ offset ++ ];
|
|
face.color.setHex( colors[ colorIndex ] );
|
|
|
|
}
|
|
|
|
|
|
if ( hasFaceVertexColor ) {
|
|
|
|
for ( i = 0; i < 3; i ++ ) {
|
|
|
|
colorIndex = faces[ offset ++ ];
|
|
face.vertexColors.push( new Color( colors[ colorIndex ] ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.faces.push( face );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function parseSkin( json, geometry ) {
|
|
|
|
var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
|
|
|
|
if ( json.skinWeights ) {
|
|
|
|
for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
|
|
|
|
var x = json.skinWeights[ i ];
|
|
var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
|
|
var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
|
|
var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
|
|
|
|
geometry.skinWeights.push( new Vector4( x, y, z, w ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( json.skinIndices ) {
|
|
|
|
for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
|
|
|
|
var a = json.skinIndices[ i ];
|
|
var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
|
|
var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
|
|
var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
|
|
|
|
geometry.skinIndices.push( new Vector4( a, b, c, d ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.bones = json.bones;
|
|
|
|
if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
|
|
|
|
console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
|
|
geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function parseMorphing( json, geometry ) {
|
|
|
|
var scale = json.scale;
|
|
|
|
if ( json.morphTargets !== undefined ) {
|
|
|
|
for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
|
|
|
|
geometry.morphTargets[ i ] = {};
|
|
geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
|
|
geometry.morphTargets[ i ].vertices = [];
|
|
|
|
var dstVertices = geometry.morphTargets[ i ].vertices;
|
|
var srcVertices = json.morphTargets[ i ].vertices;
|
|
|
|
for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
|
|
|
|
var vertex = new Vector3();
|
|
vertex.x = srcVertices[ v ] * scale;
|
|
vertex.y = srcVertices[ v + 1 ] * scale;
|
|
vertex.z = srcVertices[ v + 2 ] * scale;
|
|
|
|
dstVertices.push( vertex );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {
|
|
|
|
console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );
|
|
|
|
var faces = geometry.faces;
|
|
var morphColors = json.morphColors[ 0 ].colors;
|
|
|
|
for ( var i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
faces[ i ].color.fromArray( morphColors, i * 3 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function parseAnimations( json, geometry ) {
|
|
|
|
var outputAnimations = [];
|
|
|
|
// parse old style Bone/Hierarchy animations
|
|
var animations = [];
|
|
|
|
if ( json.animation !== undefined ) {
|
|
|
|
animations.push( json.animation );
|
|
|
|
}
|
|
|
|
if ( json.animations !== undefined ) {
|
|
|
|
if ( json.animations.length ) {
|
|
|
|
animations = animations.concat( json.animations );
|
|
|
|
} else {
|
|
|
|
animations.push( json.animations );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < animations.length; i ++ ) {
|
|
|
|
var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );
|
|
if ( clip ) outputAnimations.push( clip );
|
|
|
|
}
|
|
|
|
// parse implicit morph animations
|
|
if ( geometry.morphTargets ) {
|
|
|
|
// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
|
|
var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
|
|
outputAnimations = outputAnimations.concat( morphAnimationClips );
|
|
|
|
}
|
|
|
|
if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
|
|
|
|
}
|
|
|
|
return function ( json, texturePath ) {
|
|
|
|
if ( json.data !== undefined ) {
|
|
|
|
// Geometry 4.0 spec
|
|
json = json.data;
|
|
|
|
}
|
|
|
|
if ( json.scale !== undefined ) {
|
|
|
|
json.scale = 1.0 / json.scale;
|
|
|
|
} else {
|
|
|
|
json.scale = 1.0;
|
|
|
|
}
|
|
|
|
var geometry = new Geometry();
|
|
|
|
parseModel( json, geometry );
|
|
parseSkin( json, geometry );
|
|
parseMorphing( json, geometry );
|
|
parseAnimations( json, geometry );
|
|
|
|
geometry.computeFaceNormals();
|
|
geometry.computeBoundingSphere();
|
|
|
|
if ( json.materials === undefined || json.materials.length === 0 ) {
|
|
|
|
return { geometry: geometry };
|
|
|
|
} else {
|
|
|
|
var materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );
|
|
|
|
return { geometry: geometry, materials: materials };
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} )()
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function ObjectLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
this.texturePath = '';
|
|
|
|
}
|
|
|
|
Object.assign( ObjectLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
if ( this.texturePath === '' ) {
|
|
|
|
this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );
|
|
|
|
}
|
|
|
|
var scope = this;
|
|
|
|
var loader = new FileLoader( scope.manager );
|
|
loader.load( url, function ( text ) {
|
|
|
|
var json = null;
|
|
|
|
try {
|
|
|
|
json = JSON.parse( text );
|
|
|
|
} catch ( error ) {
|
|
|
|
if ( onError !== undefined ) onError( error );
|
|
|
|
console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var metadata = json.metadata;
|
|
|
|
if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
|
|
|
|
console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' );
|
|
return;
|
|
|
|
}
|
|
|
|
scope.parse( json, onLoad );
|
|
|
|
}, onProgress, onError );
|
|
|
|
},
|
|
|
|
setTexturePath: function ( value ) {
|
|
|
|
this.texturePath = value;
|
|
|
|
},
|
|
|
|
setCrossOrigin: function ( value ) {
|
|
|
|
this.crossOrigin = value;
|
|
|
|
},
|
|
|
|
parse: function ( json, onLoad ) {
|
|
|
|
var geometries = this.parseGeometries( json.geometries );
|
|
|
|
var images = this.parseImages( json.images, function () {
|
|
|
|
if ( onLoad !== undefined ) onLoad( object );
|
|
|
|
} );
|
|
|
|
var textures = this.parseTextures( json.textures, images );
|
|
var materials = this.parseMaterials( json.materials, textures );
|
|
|
|
var object = this.parseObject( json.object, geometries, materials );
|
|
|
|
if ( json.animations ) {
|
|
|
|
object.animations = this.parseAnimations( json.animations );
|
|
|
|
}
|
|
|
|
if ( json.images === undefined || json.images.length === 0 ) {
|
|
|
|
if ( onLoad !== undefined ) onLoad( object );
|
|
|
|
}
|
|
|
|
return object;
|
|
|
|
},
|
|
|
|
parseGeometries: function ( json ) {
|
|
|
|
var geometries = {};
|
|
|
|
if ( json !== undefined ) {
|
|
|
|
var geometryLoader = new JSONLoader();
|
|
var bufferGeometryLoader = new BufferGeometryLoader();
|
|
|
|
for ( var i = 0, l = json.length; i < l; i ++ ) {
|
|
|
|
var geometry;
|
|
var data = json[ i ];
|
|
|
|
switch ( data.type ) {
|
|
|
|
case 'PlaneGeometry':
|
|
case 'PlaneBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.width,
|
|
data.height,
|
|
data.widthSegments,
|
|
data.heightSegments
|
|
);
|
|
|
|
break;
|
|
|
|
case 'BoxGeometry':
|
|
case 'BoxBufferGeometry':
|
|
case 'CubeGeometry': // backwards compatible
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.width,
|
|
data.height,
|
|
data.depth,
|
|
data.widthSegments,
|
|
data.heightSegments,
|
|
data.depthSegments
|
|
);
|
|
|
|
break;
|
|
|
|
case 'CircleGeometry':
|
|
case 'CircleBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.segments,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'CylinderGeometry':
|
|
case 'CylinderBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radiusTop,
|
|
data.radiusBottom,
|
|
data.height,
|
|
data.radialSegments,
|
|
data.heightSegments,
|
|
data.openEnded,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'ConeGeometry':
|
|
case 'ConeBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.height,
|
|
data.radialSegments,
|
|
data.heightSegments,
|
|
data.openEnded,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'SphereGeometry':
|
|
case 'SphereBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.widthSegments,
|
|
data.heightSegments,
|
|
data.phiStart,
|
|
data.phiLength,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'DodecahedronGeometry':
|
|
case 'IcosahedronGeometry':
|
|
case 'OctahedronGeometry':
|
|
case 'TetrahedronGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.detail
|
|
);
|
|
|
|
break;
|
|
|
|
case 'RingGeometry':
|
|
case 'RingBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.innerRadius,
|
|
data.outerRadius,
|
|
data.thetaSegments,
|
|
data.phiSegments,
|
|
data.thetaStart,
|
|
data.thetaLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'TorusGeometry':
|
|
case 'TorusBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.tube,
|
|
data.radialSegments,
|
|
data.tubularSegments,
|
|
data.arc
|
|
);
|
|
|
|
break;
|
|
|
|
case 'TorusKnotGeometry':
|
|
case 'TorusKnotBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.radius,
|
|
data.tube,
|
|
data.tubularSegments,
|
|
data.radialSegments,
|
|
data.p,
|
|
data.q
|
|
);
|
|
|
|
break;
|
|
|
|
case 'LatheGeometry':
|
|
case 'LatheBufferGeometry':
|
|
|
|
geometry = new Geometries[ data.type ](
|
|
data.points,
|
|
data.segments,
|
|
data.phiStart,
|
|
data.phiLength
|
|
);
|
|
|
|
break;
|
|
|
|
case 'BufferGeometry':
|
|
|
|
geometry = bufferGeometryLoader.parse( data );
|
|
|
|
break;
|
|
|
|
case 'Geometry':
|
|
|
|
geometry = geometryLoader.parse( data, this.texturePath ).geometry;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
geometry.uuid = data.uuid;
|
|
|
|
if ( data.name !== undefined ) geometry.name = data.name;
|
|
|
|
geometries[ data.uuid ] = geometry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return geometries;
|
|
|
|
},
|
|
|
|
parseMaterials: function ( json, textures ) {
|
|
|
|
var materials = {};
|
|
|
|
if ( json !== undefined ) {
|
|
|
|
var loader = new MaterialLoader();
|
|
loader.setTextures( textures );
|
|
|
|
for ( var i = 0, l = json.length; i < l; i ++ ) {
|
|
|
|
var data = json[ i ];
|
|
|
|
if ( data.type === 'MultiMaterial' ) {
|
|
|
|
// Deprecated
|
|
|
|
var array = [];
|
|
|
|
for ( var j = 0; j < data.materials.length; j ++ ) {
|
|
|
|
array.push( loader.parse( data.materials[ j ] ) );
|
|
|
|
}
|
|
|
|
materials[ data.uuid ] = array;
|
|
|
|
} else {
|
|
|
|
materials[ data.uuid ] = loader.parse( data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return materials;
|
|
|
|
},
|
|
|
|
parseAnimations: function ( json ) {
|
|
|
|
var animations = [];
|
|
|
|
for ( var i = 0; i < json.length; i ++ ) {
|
|
|
|
var clip = AnimationClip.parse( json[ i ] );
|
|
|
|
animations.push( clip );
|
|
|
|
}
|
|
|
|
return animations;
|
|
|
|
},
|
|
|
|
parseImages: function ( json, onLoad ) {
|
|
|
|
var scope = this;
|
|
var images = {};
|
|
|
|
function loadImage( url ) {
|
|
|
|
scope.manager.itemStart( url );
|
|
|
|
return loader.load( url, function () {
|
|
|
|
scope.manager.itemEnd( url );
|
|
|
|
}, undefined, function () {
|
|
|
|
scope.manager.itemEnd( url );
|
|
scope.manager.itemError( url );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
if ( json !== undefined && json.length > 0 ) {
|
|
|
|
var manager = new LoadingManager( onLoad );
|
|
|
|
var loader = new ImageLoader( manager );
|
|
loader.setCrossOrigin( this.crossOrigin );
|
|
|
|
for ( var i = 0, l = json.length; i < l; i ++ ) {
|
|
|
|
var image = json[ i ];
|
|
var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;
|
|
|
|
images[ image.uuid ] = loadImage( path );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return images;
|
|
|
|
},
|
|
|
|
parseTextures: function ( json, images ) {
|
|
|
|
function parseConstant( value, type ) {
|
|
|
|
if ( typeof( value ) === 'number' ) return value;
|
|
|
|
console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
|
|
|
|
return type[ value ];
|
|
|
|
}
|
|
|
|
var textures = {};
|
|
|
|
if ( json !== undefined ) {
|
|
|
|
for ( var i = 0, l = json.length; i < l; i ++ ) {
|
|
|
|
var data = json[ i ];
|
|
|
|
if ( data.image === undefined ) {
|
|
|
|
console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
|
|
|
|
}
|
|
|
|
if ( images[ data.image ] === undefined ) {
|
|
|
|
console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
|
|
|
|
}
|
|
|
|
var texture = new Texture( images[ data.image ] );
|
|
texture.needsUpdate = true;
|
|
|
|
texture.uuid = data.uuid;
|
|
|
|
if ( data.name !== undefined ) texture.name = data.name;
|
|
|
|
if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
|
|
|
|
if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
|
|
if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
|
|
if ( data.wrap !== undefined ) {
|
|
|
|
texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
|
|
texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );
|
|
|
|
}
|
|
|
|
if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
|
|
if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
|
|
if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
|
|
|
|
if ( data.flipY !== undefined ) texture.flipY = data.flipY;
|
|
|
|
textures[ data.uuid ] = texture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return textures;
|
|
|
|
},
|
|
|
|
parseObject: function () {
|
|
|
|
var matrix = new Matrix4();
|
|
|
|
return function parseObject( data, geometries, materials ) {
|
|
|
|
var object;
|
|
|
|
function getGeometry( name ) {
|
|
|
|
if ( geometries[ name ] === undefined ) {
|
|
|
|
console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
|
|
|
|
}
|
|
|
|
return geometries[ name ];
|
|
|
|
}
|
|
|
|
function getMaterial( name ) {
|
|
|
|
if ( name === undefined ) return undefined;
|
|
|
|
if ( Array.isArray( name ) ) {
|
|
|
|
var array = [];
|
|
|
|
for ( var i = 0, l = name.length; i < l; i ++ ) {
|
|
|
|
var uuid = name[ i ];
|
|
|
|
if ( materials[ uuid ] === undefined ) {
|
|
|
|
console.warn( 'THREE.ObjectLoader: Undefined material', uuid );
|
|
|
|
}
|
|
|
|
array.push( materials[ uuid ] );
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
if ( materials[ name ] === undefined ) {
|
|
|
|
console.warn( 'THREE.ObjectLoader: Undefined material', name );
|
|
|
|
}
|
|
|
|
return materials[ name ];
|
|
|
|
}
|
|
|
|
switch ( data.type ) {
|
|
|
|
case 'Scene':
|
|
|
|
object = new Scene();
|
|
|
|
if ( data.background !== undefined ) {
|
|
|
|
if ( Number.isInteger( data.background ) ) {
|
|
|
|
object.background = new Color( data.background );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( data.fog !== undefined ) {
|
|
|
|
if ( data.fog.type === 'Fog' ) {
|
|
|
|
object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
|
|
|
|
} else if ( data.fog.type === 'FogExp2' ) {
|
|
|
|
object.fog = new FogExp2( data.fog.color, data.fog.density );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'PerspectiveCamera':
|
|
|
|
object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
|
|
|
|
if ( data.focus !== undefined ) object.focus = data.focus;
|
|
if ( data.zoom !== undefined ) object.zoom = data.zoom;
|
|
if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
|
|
if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
|
|
if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );
|
|
|
|
break;
|
|
|
|
case 'OrthographicCamera':
|
|
|
|
object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
|
|
|
|
break;
|
|
|
|
case 'AmbientLight':
|
|
|
|
object = new AmbientLight( data.color, data.intensity );
|
|
|
|
break;
|
|
|
|
case 'DirectionalLight':
|
|
|
|
object = new DirectionalLight( data.color, data.intensity );
|
|
|
|
break;
|
|
|
|
case 'PointLight':
|
|
|
|
object = new PointLight( data.color, data.intensity, data.distance, data.decay );
|
|
|
|
break;
|
|
|
|
case 'RectAreaLight':
|
|
|
|
object = new RectAreaLight( data.color, data.intensity, data.width, data.height );
|
|
|
|
break;
|
|
|
|
case 'SpotLight':
|
|
|
|
object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
|
|
|
|
break;
|
|
|
|
case 'HemisphereLight':
|
|
|
|
object = new HemisphereLight( data.color, data.groundColor, data.intensity );
|
|
|
|
break;
|
|
|
|
case 'SkinnedMesh':
|
|
|
|
console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
|
|
|
|
case 'Mesh':
|
|
|
|
var geometry = getGeometry( data.geometry );
|
|
var material = getMaterial( data.material );
|
|
|
|
if ( geometry.bones && geometry.bones.length > 0 ) {
|
|
|
|
object = new SkinnedMesh( geometry, material );
|
|
|
|
} else {
|
|
|
|
object = new Mesh( geometry, material );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'LOD':
|
|
|
|
object = new LOD();
|
|
|
|
break;
|
|
|
|
case 'Line':
|
|
|
|
object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
|
|
|
|
break;
|
|
|
|
case 'LineLoop':
|
|
|
|
object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );
|
|
|
|
break;
|
|
|
|
case 'LineSegments':
|
|
|
|
object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
|
|
|
|
break;
|
|
|
|
case 'PointCloud':
|
|
case 'Points':
|
|
|
|
object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
|
|
|
|
break;
|
|
|
|
case 'Sprite':
|
|
|
|
object = new Sprite( getMaterial( data.material ) );
|
|
|
|
break;
|
|
|
|
case 'Group':
|
|
|
|
object = new Group();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
object = new Object3D();
|
|
|
|
}
|
|
|
|
object.uuid = data.uuid;
|
|
|
|
if ( data.name !== undefined ) object.name = data.name;
|
|
if ( data.matrix !== undefined ) {
|
|
|
|
matrix.fromArray( data.matrix );
|
|
matrix.decompose( object.position, object.quaternion, object.scale );
|
|
|
|
} else {
|
|
|
|
if ( data.position !== undefined ) object.position.fromArray( data.position );
|
|
if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
|
|
if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
|
|
if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
|
|
|
|
}
|
|
|
|
if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
|
|
if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
|
|
|
|
if ( data.shadow ) {
|
|
|
|
if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
|
|
if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
|
|
if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
|
|
if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );
|
|
|
|
}
|
|
|
|
if ( data.visible !== undefined ) object.visible = data.visible;
|
|
if ( data.userData !== undefined ) object.userData = data.userData;
|
|
|
|
if ( data.children !== undefined ) {
|
|
|
|
for ( var child in data.children ) {
|
|
|
|
object.add( this.parseObject( data.children[ child ], geometries, materials ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( data.type === 'LOD' ) {
|
|
|
|
var levels = data.levels;
|
|
|
|
for ( var l = 0; l < levels.length; l ++ ) {
|
|
|
|
var level = levels[ l ];
|
|
var child = object.getObjectByProperty( 'uuid', level.object );
|
|
|
|
if ( child !== undefined ) {
|
|
|
|
object.addLevel( child, level.distance );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return object;
|
|
|
|
};
|
|
|
|
}()
|
|
|
|
} );
|
|
|
|
var TEXTURE_MAPPING = {
|
|
UVMapping: UVMapping,
|
|
CubeReflectionMapping: CubeReflectionMapping,
|
|
CubeRefractionMapping: CubeRefractionMapping,
|
|
EquirectangularReflectionMapping: EquirectangularReflectionMapping,
|
|
EquirectangularRefractionMapping: EquirectangularRefractionMapping,
|
|
SphericalReflectionMapping: SphericalReflectionMapping,
|
|
CubeUVReflectionMapping: CubeUVReflectionMapping,
|
|
CubeUVRefractionMapping: CubeUVRefractionMapping
|
|
};
|
|
|
|
var TEXTURE_WRAPPING = {
|
|
RepeatWrapping: RepeatWrapping,
|
|
ClampToEdgeWrapping: ClampToEdgeWrapping,
|
|
MirroredRepeatWrapping: MirroredRepeatWrapping
|
|
};
|
|
|
|
var TEXTURE_FILTER = {
|
|
NearestFilter: NearestFilter,
|
|
NearestMipMapNearestFilter: NearestMipMapNearestFilter,
|
|
NearestMipMapLinearFilter: NearestMipMapLinearFilter,
|
|
LinearFilter: LinearFilter,
|
|
LinearMipMapNearestFilter: LinearMipMapNearestFilter,
|
|
LinearMipMapLinearFilter: LinearMipMapLinearFilter
|
|
};
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
*
|
|
* Bezier Curves formulas obtained from
|
|
* http://en.wikipedia.org/wiki/Bézier_curve
|
|
*/
|
|
|
|
function CatmullRom( t, p0, p1, p2, p3 ) {
|
|
|
|
var v0 = ( p2 - p0 ) * 0.5;
|
|
var v1 = ( p3 - p1 ) * 0.5;
|
|
var t2 = t * t;
|
|
var t3 = t * t2;
|
|
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function QuadraticBezierP0( t, p ) {
|
|
|
|
var k = 1 - t;
|
|
return k * k * p;
|
|
|
|
}
|
|
|
|
function QuadraticBezierP1( t, p ) {
|
|
|
|
return 2 * ( 1 - t ) * t * p;
|
|
|
|
}
|
|
|
|
function QuadraticBezierP2( t, p ) {
|
|
|
|
return t * t * p;
|
|
|
|
}
|
|
|
|
function QuadraticBezier( t, p0, p1, p2 ) {
|
|
|
|
return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
|
|
QuadraticBezierP2( t, p2 );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function CubicBezierP0( t, p ) {
|
|
|
|
var k = 1 - t;
|
|
return k * k * k * p;
|
|
|
|
}
|
|
|
|
function CubicBezierP1( t, p ) {
|
|
|
|
var k = 1 - t;
|
|
return 3 * k * k * t * p;
|
|
|
|
}
|
|
|
|
function CubicBezierP2( t, p ) {
|
|
|
|
return 3 * ( 1 - t ) * t * t * p;
|
|
|
|
}
|
|
|
|
function CubicBezierP3( t, p ) {
|
|
|
|
return t * t * t * p;
|
|
|
|
}
|
|
|
|
function CubicBezier( t, p0, p1, p2, p3 ) {
|
|
|
|
return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
|
|
CubicBezierP3( t, p3 );
|
|
|
|
}
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* Extensible curve object
|
|
*
|
|
* Some common of curve methods:
|
|
* .getPoint(t), getTangent(t)
|
|
* .getPointAt(u), getTangentAt(u)
|
|
* .getPoints(), .getSpacedPoints()
|
|
* .getLength()
|
|
* .updateArcLengths()
|
|
*
|
|
* This following curves inherit from THREE.Curve:
|
|
*
|
|
* -- 2D curves --
|
|
* THREE.ArcCurve
|
|
* THREE.CubicBezierCurve
|
|
* THREE.EllipseCurve
|
|
* THREE.LineCurve
|
|
* THREE.QuadraticBezierCurve
|
|
* THREE.SplineCurve
|
|
*
|
|
* -- 3D curves --
|
|
* THREE.CatmullRomCurve3
|
|
* THREE.CubicBezierCurve3
|
|
* THREE.LineCurve3
|
|
* THREE.QuadraticBezierCurve3
|
|
*
|
|
* A series of curves can be represented as a THREE.CurvePath.
|
|
*
|
|
**/
|
|
|
|
/**************************************************************
|
|
* Abstract Curve base class
|
|
**************************************************************/
|
|
|
|
function Curve() {
|
|
|
|
this.arcLengthDivisions = 200;
|
|
|
|
}
|
|
|
|
Object.assign( Curve.prototype, {
|
|
|
|
// Virtual base class method to overwrite and implement in subclasses
|
|
// - t [0 .. 1]
|
|
|
|
getPoint: function () {
|
|
|
|
console.warn( 'THREE.Curve: .getPoint() not implemented.' );
|
|
return null;
|
|
|
|
},
|
|
|
|
// Get point at relative position in curve according to arc length
|
|
// - u [0 .. 1]
|
|
|
|
getPointAt: function ( u ) {
|
|
|
|
var t = this.getUtoTmapping( u );
|
|
return this.getPoint( t );
|
|
|
|
},
|
|
|
|
// Get sequence of points using getPoint( t )
|
|
|
|
getPoints: function ( divisions ) {
|
|
|
|
if ( divisions === undefined ) divisions = 5;
|
|
|
|
var points = [];
|
|
|
|
for ( var d = 0; d <= divisions; d ++ ) {
|
|
|
|
points.push( this.getPoint( d / divisions ) );
|
|
|
|
}
|
|
|
|
return points;
|
|
|
|
},
|
|
|
|
// Get sequence of points using getPointAt( u )
|
|
|
|
getSpacedPoints: function ( divisions ) {
|
|
|
|
if ( divisions === undefined ) divisions = 5;
|
|
|
|
var points = [];
|
|
|
|
for ( var d = 0; d <= divisions; d ++ ) {
|
|
|
|
points.push( this.getPointAt( d / divisions ) );
|
|
|
|
}
|
|
|
|
return points;
|
|
|
|
},
|
|
|
|
// Get total curve arc length
|
|
|
|
getLength: function () {
|
|
|
|
var lengths = this.getLengths();
|
|
return lengths[ lengths.length - 1 ];
|
|
|
|
},
|
|
|
|
// Get list of cumulative segment lengths
|
|
|
|
getLengths: function ( divisions ) {
|
|
|
|
if ( divisions === undefined ) divisions = this.arcLengthDivisions;
|
|
|
|
if ( this.cacheArcLengths &&
|
|
( this.cacheArcLengths.length === divisions + 1 ) &&
|
|
! this.needsUpdate ) {
|
|
|
|
return this.cacheArcLengths;
|
|
|
|
}
|
|
|
|
this.needsUpdate = false;
|
|
|
|
var cache = [];
|
|
var current, last = this.getPoint( 0 );
|
|
var p, sum = 0;
|
|
|
|
cache.push( 0 );
|
|
|
|
for ( p = 1; p <= divisions; p ++ ) {
|
|
|
|
current = this.getPoint( p / divisions );
|
|
sum += current.distanceTo( last );
|
|
cache.push( sum );
|
|
last = current;
|
|
|
|
}
|
|
|
|
this.cacheArcLengths = cache;
|
|
|
|
return cache; // { sums: cache, sum: sum }; Sum is in the last element.
|
|
|
|
},
|
|
|
|
updateArcLengths: function () {
|
|
|
|
this.needsUpdate = true;
|
|
this.getLengths();
|
|
|
|
},
|
|
|
|
// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
|
|
|
|
getUtoTmapping: function ( u, distance ) {
|
|
|
|
var arcLengths = this.getLengths();
|
|
|
|
var i = 0, il = arcLengths.length;
|
|
|
|
var targetArcLength; // The targeted u distance value to get
|
|
|
|
if ( distance ) {
|
|
|
|
targetArcLength = distance;
|
|
|
|
} else {
|
|
|
|
targetArcLength = u * arcLengths[ il - 1 ];
|
|
|
|
}
|
|
|
|
// binary search for the index with largest value smaller than target u distance
|
|
|
|
var low = 0, high = il - 1, comparison;
|
|
|
|
while ( low <= high ) {
|
|
|
|
i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
|
|
|
|
comparison = arcLengths[ i ] - targetArcLength;
|
|
|
|
if ( comparison < 0 ) {
|
|
|
|
low = i + 1;
|
|
|
|
} else if ( comparison > 0 ) {
|
|
|
|
high = i - 1;
|
|
|
|
} else {
|
|
|
|
high = i;
|
|
break;
|
|
|
|
// DONE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i = high;
|
|
|
|
if ( arcLengths[ i ] === targetArcLength ) {
|
|
|
|
return i / ( il - 1 );
|
|
|
|
}
|
|
|
|
// we could get finer grain at lengths, or use simple interpolation between two points
|
|
|
|
var lengthBefore = arcLengths[ i ];
|
|
var lengthAfter = arcLengths[ i + 1 ];
|
|
|
|
var segmentLength = lengthAfter - lengthBefore;
|
|
|
|
// determine where we are between the 'before' and 'after' points
|
|
|
|
var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
|
|
|
|
// add that fractional amount to t
|
|
|
|
var t = ( i + segmentFraction ) / ( il - 1 );
|
|
|
|
return t;
|
|
|
|
},
|
|
|
|
// Returns a unit vector tangent at t
|
|
// In case any sub curve does not implement its tangent derivation,
|
|
// 2 points a small delta apart will be used to find its gradient
|
|
// which seems to give a reasonable approximation
|
|
|
|
getTangent: function ( t ) {
|
|
|
|
var delta = 0.0001;
|
|
var t1 = t - delta;
|
|
var t2 = t + delta;
|
|
|
|
// Capping in case of danger
|
|
|
|
if ( t1 < 0 ) t1 = 0;
|
|
if ( t2 > 1 ) t2 = 1;
|
|
|
|
var pt1 = this.getPoint( t1 );
|
|
var pt2 = this.getPoint( t2 );
|
|
|
|
var vec = pt2.clone().sub( pt1 );
|
|
return vec.normalize();
|
|
|
|
},
|
|
|
|
getTangentAt: function ( u ) {
|
|
|
|
var t = this.getUtoTmapping( u );
|
|
return this.getTangent( t );
|
|
|
|
},
|
|
|
|
computeFrenetFrames: function ( segments, closed ) {
|
|
|
|
// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
|
|
|
|
var normal = new Vector3();
|
|
|
|
var tangents = [];
|
|
var normals = [];
|
|
var binormals = [];
|
|
|
|
var vec = new Vector3();
|
|
var mat = new Matrix4();
|
|
|
|
var i, u, theta;
|
|
|
|
// compute the tangent vectors for each segment on the curve
|
|
|
|
for ( i = 0; i <= segments; i ++ ) {
|
|
|
|
u = i / segments;
|
|
|
|
tangents[ i ] = this.getTangentAt( u );
|
|
tangents[ i ].normalize();
|
|
|
|
}
|
|
|
|
// select an initial normal vector perpendicular to the first tangent vector,
|
|
// and in the direction of the minimum tangent xyz component
|
|
|
|
normals[ 0 ] = new Vector3();
|
|
binormals[ 0 ] = new Vector3();
|
|
var min = Number.MAX_VALUE;
|
|
var tx = Math.abs( tangents[ 0 ].x );
|
|
var ty = Math.abs( tangents[ 0 ].y );
|
|
var tz = Math.abs( tangents[ 0 ].z );
|
|
|
|
if ( tx <= min ) {
|
|
|
|
min = tx;
|
|
normal.set( 1, 0, 0 );
|
|
|
|
}
|
|
|
|
if ( ty <= min ) {
|
|
|
|
min = ty;
|
|
normal.set( 0, 1, 0 );
|
|
|
|
}
|
|
|
|
if ( tz <= min ) {
|
|
|
|
normal.set( 0, 0, 1 );
|
|
|
|
}
|
|
|
|
vec.crossVectors( tangents[ 0 ], normal ).normalize();
|
|
|
|
normals[ 0 ].crossVectors( tangents[ 0 ], vec );
|
|
binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
|
|
|
|
|
|
// compute the slowly-varying normal and binormal vectors for each segment on the curve
|
|
|
|
for ( i = 1; i <= segments; i ++ ) {
|
|
|
|
normals[ i ] = normals[ i - 1 ].clone();
|
|
|
|
binormals[ i ] = binormals[ i - 1 ].clone();
|
|
|
|
vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
|
|
|
|
if ( vec.length() > Number.EPSILON ) {
|
|
|
|
vec.normalize();
|
|
|
|
theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors
|
|
|
|
normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
|
|
|
|
}
|
|
|
|
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
|
|
|
|
}
|
|
|
|
// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
|
|
|
|
if ( closed === true ) {
|
|
|
|
theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
|
|
theta /= segments;
|
|
|
|
if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
|
|
|
|
theta = - theta;
|
|
|
|
}
|
|
|
|
for ( i = 1; i <= segments; i ++ ) {
|
|
|
|
// twist a little...
|
|
normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
|
|
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
tangents: tangents,
|
|
normals: normals,
|
|
binormals: binormals
|
|
};
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
function LineCurve( v1, v2 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
|
|
}
|
|
|
|
LineCurve.prototype = Object.create( Curve.prototype );
|
|
LineCurve.prototype.constructor = LineCurve;
|
|
|
|
LineCurve.prototype.isLineCurve = true;
|
|
|
|
LineCurve.prototype.getPoint = function ( t ) {
|
|
|
|
if ( t === 1 ) {
|
|
|
|
return this.v2.clone();
|
|
|
|
}
|
|
|
|
var point = this.v2.clone().sub( this.v1 );
|
|
point.multiplyScalar( t ).add( this.v1 );
|
|
|
|
return point;
|
|
|
|
};
|
|
|
|
// Line curve is linear, so we can overwrite default getPointAt
|
|
|
|
LineCurve.prototype.getPointAt = function ( u ) {
|
|
|
|
return this.getPoint( u );
|
|
|
|
};
|
|
|
|
LineCurve.prototype.getTangent = function ( t ) {
|
|
|
|
var tangent = this.v2.clone().sub( this.v1 );
|
|
|
|
return tangent.normalize();
|
|
|
|
};
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
*
|
|
**/
|
|
|
|
/**************************************************************
|
|
* Curved Path - a curve path is simply a array of connected
|
|
* curves, but retains the api of a curve
|
|
**************************************************************/
|
|
|
|
function CurvePath() {
|
|
|
|
Curve.call( this );
|
|
|
|
this.curves = [];
|
|
|
|
this.autoClose = false; // Automatically closes the path
|
|
|
|
}
|
|
|
|
CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
|
|
|
|
constructor: CurvePath,
|
|
|
|
add: function ( curve ) {
|
|
|
|
this.curves.push( curve );
|
|
|
|
},
|
|
|
|
closePath: function () {
|
|
|
|
// Add a line curve if start and end of lines are not connected
|
|
var startPoint = this.curves[ 0 ].getPoint( 0 );
|
|
var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
|
|
|
|
if ( ! startPoint.equals( endPoint ) ) {
|
|
|
|
this.curves.push( new LineCurve( endPoint, startPoint ) );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// To get accurate point with reference to
|
|
// entire path distance at time t,
|
|
// following has to be done:
|
|
|
|
// 1. Length of each sub path have to be known
|
|
// 2. Locate and identify type of curve
|
|
// 3. Get t for the curve
|
|
// 4. Return curve.getPointAt(t')
|
|
|
|
getPoint: function ( t ) {
|
|
|
|
var d = t * this.getLength();
|
|
var curveLengths = this.getCurveLengths();
|
|
var i = 0;
|
|
|
|
// To think about boundaries points.
|
|
|
|
while ( i < curveLengths.length ) {
|
|
|
|
if ( curveLengths[ i ] >= d ) {
|
|
|
|
var diff = curveLengths[ i ] - d;
|
|
var curve = this.curves[ i ];
|
|
|
|
var segmentLength = curve.getLength();
|
|
var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
|
|
|
|
return curve.getPointAt( u );
|
|
|
|
}
|
|
|
|
i ++;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
// loop where sum != 0, sum > d , sum+1 <d
|
|
|
|
},
|
|
|
|
// We cannot use the default THREE.Curve getPoint() with getLength() because in
|
|
// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
|
|
// getPoint() depends on getLength
|
|
|
|
getLength: function () {
|
|
|
|
var lens = this.getCurveLengths();
|
|
return lens[ lens.length - 1 ];
|
|
|
|
},
|
|
|
|
// cacheLengths must be recalculated.
|
|
updateArcLengths: function () {
|
|
|
|
this.needsUpdate = true;
|
|
this.cacheLengths = null;
|
|
this.getCurveLengths();
|
|
|
|
},
|
|
|
|
// Compute lengths and cache them
|
|
// We cannot overwrite getLengths() because UtoT mapping uses it.
|
|
|
|
getCurveLengths: function () {
|
|
|
|
// We use cache values if curves and cache array are same length
|
|
|
|
if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
|
|
|
|
return this.cacheLengths;
|
|
|
|
}
|
|
|
|
// Get length of sub-curve
|
|
// Push sums into cached array
|
|
|
|
var lengths = [], sums = 0;
|
|
|
|
for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
|
|
|
|
sums += this.curves[ i ].getLength();
|
|
lengths.push( sums );
|
|
|
|
}
|
|
|
|
this.cacheLengths = lengths;
|
|
|
|
return lengths;
|
|
|
|
},
|
|
|
|
getSpacedPoints: function ( divisions ) {
|
|
|
|
if ( divisions === undefined ) divisions = 40;
|
|
|
|
var points = [];
|
|
|
|
for ( var i = 0; i <= divisions; i ++ ) {
|
|
|
|
points.push( this.getPoint( i / divisions ) );
|
|
|
|
}
|
|
|
|
if ( this.autoClose ) {
|
|
|
|
points.push( points[ 0 ] );
|
|
|
|
}
|
|
|
|
return points;
|
|
|
|
},
|
|
|
|
getPoints: function ( divisions ) {
|
|
|
|
divisions = divisions || 12;
|
|
|
|
var points = [], last;
|
|
|
|
for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) {
|
|
|
|
var curve = curves[ i ];
|
|
var resolution = (curve && curve.isEllipseCurve) ? divisions * 2
|
|
: (curve && curve.isLineCurve) ? 1
|
|
: (curve && curve.isSplineCurve) ? divisions * curve.points.length
|
|
: divisions;
|
|
|
|
var pts = curve.getPoints( resolution );
|
|
|
|
for ( var j = 0; j < pts.length; j++ ) {
|
|
|
|
var point = pts[ j ];
|
|
|
|
if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates
|
|
|
|
points.push( point );
|
|
last = point;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.autoClose && points.length > 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {
|
|
|
|
points.push( points[ 0 ] );
|
|
|
|
}
|
|
|
|
return points;
|
|
|
|
},
|
|
|
|
/**************************************************************
|
|
* Create Geometries Helpers
|
|
**************************************************************/
|
|
|
|
/// Generate geometry from path points (for Line or Points objects)
|
|
|
|
createPointsGeometry: function ( divisions ) {
|
|
|
|
var pts = this.getPoints( divisions );
|
|
return this.createGeometry( pts );
|
|
|
|
},
|
|
|
|
// Generate geometry from equidistant sampling along the path
|
|
|
|
createSpacedPointsGeometry: function ( divisions ) {
|
|
|
|
var pts = this.getSpacedPoints( divisions );
|
|
return this.createGeometry( pts );
|
|
|
|
},
|
|
|
|
createGeometry: function ( points ) {
|
|
|
|
var geometry = new Geometry();
|
|
|
|
for ( var i = 0, l = points.length; i < l; i ++ ) {
|
|
|
|
var point = points[ i ];
|
|
geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
|
|
|
|
}
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.aX = aX;
|
|
this.aY = aY;
|
|
|
|
this.xRadius = xRadius;
|
|
this.yRadius = yRadius;
|
|
|
|
this.aStartAngle = aStartAngle;
|
|
this.aEndAngle = aEndAngle;
|
|
|
|
this.aClockwise = aClockwise;
|
|
|
|
this.aRotation = aRotation || 0;
|
|
|
|
}
|
|
|
|
EllipseCurve.prototype = Object.create( Curve.prototype );
|
|
EllipseCurve.prototype.constructor = EllipseCurve;
|
|
|
|
EllipseCurve.prototype.isEllipseCurve = true;
|
|
|
|
EllipseCurve.prototype.getPoint = function ( t ) {
|
|
|
|
var twoPi = Math.PI * 2;
|
|
var deltaAngle = this.aEndAngle - this.aStartAngle;
|
|
var samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
|
|
|
|
// ensures that deltaAngle is 0 .. 2 PI
|
|
while ( deltaAngle < 0 ) deltaAngle += twoPi;
|
|
while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
|
|
|
|
if ( deltaAngle < Number.EPSILON ) {
|
|
|
|
if ( samePoints ) {
|
|
|
|
deltaAngle = 0;
|
|
|
|
} else {
|
|
|
|
deltaAngle = twoPi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.aClockwise === true && ! samePoints ) {
|
|
|
|
if ( deltaAngle === twoPi ) {
|
|
|
|
deltaAngle = - twoPi;
|
|
|
|
} else {
|
|
|
|
deltaAngle = deltaAngle - twoPi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var angle = this.aStartAngle + t * deltaAngle;
|
|
var x = this.aX + this.xRadius * Math.cos( angle );
|
|
var y = this.aY + this.yRadius * Math.sin( angle );
|
|
|
|
if ( this.aRotation !== 0 ) {
|
|
|
|
var cos = Math.cos( this.aRotation );
|
|
var sin = Math.sin( this.aRotation );
|
|
|
|
var tx = x - this.aX;
|
|
var ty = y - this.aY;
|
|
|
|
// Rotate the point about the center of the ellipse.
|
|
x = tx * cos - ty * sin + this.aX;
|
|
y = tx * sin + ty * cos + this.aY;
|
|
|
|
}
|
|
|
|
return new Vector2( x, y );
|
|
|
|
};
|
|
|
|
function SplineCurve( points /* array of Vector2 */ ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.points = ( points === undefined ) ? [] : points;
|
|
|
|
}
|
|
|
|
SplineCurve.prototype = Object.create( Curve.prototype );
|
|
SplineCurve.prototype.constructor = SplineCurve;
|
|
|
|
SplineCurve.prototype.isSplineCurve = true;
|
|
|
|
SplineCurve.prototype.getPoint = function ( t ) {
|
|
|
|
var points = this.points;
|
|
var point = ( points.length - 1 ) * t;
|
|
|
|
var intPoint = Math.floor( point );
|
|
var weight = point - intPoint;
|
|
|
|
var point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
|
|
var point1 = points[ intPoint ];
|
|
var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
|
|
var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
|
|
|
|
return new Vector2(
|
|
CatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),
|
|
CatmullRom( weight, point0.y, point1.y, point2.y, point3.y )
|
|
);
|
|
|
|
};
|
|
|
|
function CubicBezierCurve( v0, v1, v2, v3 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v0 = v0;
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
this.v3 = v3;
|
|
|
|
}
|
|
|
|
CubicBezierCurve.prototype = Object.create( Curve.prototype );
|
|
CubicBezierCurve.prototype.constructor = CubicBezierCurve;
|
|
|
|
CubicBezierCurve.prototype.getPoint = function ( t ) {
|
|
|
|
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
|
|
|
return new Vector2(
|
|
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
|
CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
|
|
);
|
|
|
|
};
|
|
|
|
function QuadraticBezierCurve( v0, v1, v2 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v0 = v0;
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
|
|
}
|
|
|
|
QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
|
|
QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
|
|
|
|
QuadraticBezierCurve.prototype.getPoint = function ( t ) {
|
|
|
|
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
|
|
|
return new Vector2(
|
|
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
|
QuadraticBezier( t, v0.y, v1.y, v2.y )
|
|
);
|
|
|
|
};
|
|
|
|
var PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {
|
|
|
|
fromPoints: function ( vectors ) {
|
|
|
|
this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
|
|
|
|
for ( var i = 1, l = vectors.length; i < l; i ++ ) {
|
|
|
|
this.lineTo( vectors[ i ].x, vectors[ i ].y );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
moveTo: function ( x, y ) {
|
|
|
|
this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?
|
|
|
|
},
|
|
|
|
lineTo: function ( x, y ) {
|
|
|
|
var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
|
|
this.curves.push( curve );
|
|
|
|
this.currentPoint.set( x, y );
|
|
|
|
},
|
|
|
|
quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
|
|
|
|
var curve = new QuadraticBezierCurve(
|
|
this.currentPoint.clone(),
|
|
new Vector2( aCPx, aCPy ),
|
|
new Vector2( aX, aY )
|
|
);
|
|
|
|
this.curves.push( curve );
|
|
|
|
this.currentPoint.set( aX, aY );
|
|
|
|
},
|
|
|
|
bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
|
|
|
|
var curve = new CubicBezierCurve(
|
|
this.currentPoint.clone(),
|
|
new Vector2( aCP1x, aCP1y ),
|
|
new Vector2( aCP2x, aCP2y ),
|
|
new Vector2( aX, aY )
|
|
);
|
|
|
|
this.curves.push( curve );
|
|
|
|
this.currentPoint.set( aX, aY );
|
|
|
|
},
|
|
|
|
splineThru: function ( pts /*Array of Vector*/ ) {
|
|
|
|
var npts = [ this.currentPoint.clone() ].concat( pts );
|
|
|
|
var curve = new SplineCurve( npts );
|
|
this.curves.push( curve );
|
|
|
|
this.currentPoint.copy( pts[ pts.length - 1 ] );
|
|
|
|
},
|
|
|
|
arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
|
|
|
var x0 = this.currentPoint.x;
|
|
var y0 = this.currentPoint.y;
|
|
|
|
this.absarc( aX + x0, aY + y0, aRadius,
|
|
aStartAngle, aEndAngle, aClockwise );
|
|
|
|
},
|
|
|
|
absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
|
|
|
this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
|
|
|
|
},
|
|
|
|
ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
|
|
|
var x0 = this.currentPoint.x;
|
|
var y0 = this.currentPoint.y;
|
|
|
|
this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
|
|
|
|
},
|
|
|
|
absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
|
|
|
var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
|
|
|
|
if ( this.curves.length > 0 ) {
|
|
|
|
// if a previous curve is present, attempt to join
|
|
var firstPoint = curve.getPoint( 0 );
|
|
|
|
if ( ! firstPoint.equals( this.currentPoint ) ) {
|
|
|
|
this.lineTo( firstPoint.x, firstPoint.y );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.curves.push( curve );
|
|
|
|
var lastPoint = curve.getPoint( 1 );
|
|
this.currentPoint.copy( lastPoint );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* Creates free form 2d path using series of points, lines or curves.
|
|
**/
|
|
|
|
function Path( points ) {
|
|
|
|
CurvePath.call( this );
|
|
this.currentPoint = new Vector2();
|
|
|
|
if ( points ) {
|
|
|
|
this.fromPoints( points );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Path.prototype = PathPrototype;
|
|
PathPrototype.constructor = Path;
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* Defines a 2d shape plane using paths.
|
|
**/
|
|
|
|
// STEP 1 Create a path.
|
|
// STEP 2 Turn path into shape.
|
|
// STEP 3 ExtrudeGeometry takes in Shape/Shapes
|
|
// STEP 3a - Extract points from each shape, turn to vertices
|
|
// STEP 3b - Triangulate each shape, add faces.
|
|
|
|
function Shape() {
|
|
|
|
Path.apply( this, arguments );
|
|
|
|
this.holes = [];
|
|
|
|
}
|
|
|
|
Shape.prototype = Object.assign( Object.create( PathPrototype ), {
|
|
|
|
constructor: Shape,
|
|
|
|
getPointsHoles: function ( divisions ) {
|
|
|
|
var holesPts = [];
|
|
|
|
for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
|
|
|
|
holesPts[ i ] = this.holes[ i ].getPoints( divisions );
|
|
|
|
}
|
|
|
|
return holesPts;
|
|
|
|
},
|
|
|
|
// Get points of shape and holes (keypoints based on segments parameter)
|
|
|
|
extractAllPoints: function ( divisions ) {
|
|
|
|
return {
|
|
|
|
shape: this.getPoints( divisions ),
|
|
holes: this.getPointsHoles( divisions )
|
|
|
|
};
|
|
|
|
},
|
|
|
|
extractPoints: function ( divisions ) {
|
|
|
|
return this.extractAllPoints( divisions );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* minimal class for proxing functions to Path. Replaces old "extractSubpaths()"
|
|
**/
|
|
|
|
function ShapePath() {
|
|
|
|
this.subPaths = [];
|
|
this.currentPath = null;
|
|
|
|
}
|
|
|
|
Object.assign( ShapePath.prototype, {
|
|
|
|
moveTo: function ( x, y ) {
|
|
|
|
this.currentPath = new Path();
|
|
this.subPaths.push( this.currentPath );
|
|
this.currentPath.moveTo( x, y );
|
|
|
|
},
|
|
|
|
lineTo: function ( x, y ) {
|
|
|
|
this.currentPath.lineTo( x, y );
|
|
|
|
},
|
|
|
|
quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
|
|
|
|
this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
|
|
|
|
},
|
|
|
|
bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
|
|
|
|
this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
|
|
|
|
},
|
|
|
|
splineThru: function ( pts ) {
|
|
|
|
this.currentPath.splineThru( pts );
|
|
|
|
},
|
|
|
|
toShapes: function ( isCCW, noHoles ) {
|
|
|
|
function toShapesNoHoles( inSubpaths ) {
|
|
|
|
var shapes = [];
|
|
|
|
for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {
|
|
|
|
var tmpPath = inSubpaths[ i ];
|
|
|
|
var tmpShape = new Shape();
|
|
tmpShape.curves = tmpPath.curves;
|
|
|
|
shapes.push( tmpShape );
|
|
|
|
}
|
|
|
|
return shapes;
|
|
|
|
}
|
|
|
|
function isPointInsidePolygon( inPt, inPolygon ) {
|
|
|
|
var polyLen = inPolygon.length;
|
|
|
|
// inPt on polygon contour => immediate success or
|
|
// toggling of inside/outside at every single! intersection point of an edge
|
|
// with the horizontal line through inPt, left of inPt
|
|
// not counting lowerY endpoints of edges and whole edges on that line
|
|
var inside = false;
|
|
for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
|
|
|
|
var edgeLowPt = inPolygon[ p ];
|
|
var edgeHighPt = inPolygon[ q ];
|
|
|
|
var edgeDx = edgeHighPt.x - edgeLowPt.x;
|
|
var edgeDy = edgeHighPt.y - edgeLowPt.y;
|
|
|
|
if ( Math.abs( edgeDy ) > Number.EPSILON ) {
|
|
|
|
// not parallel
|
|
if ( edgeDy < 0 ) {
|
|
|
|
edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
|
|
edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
|
|
|
|
}
|
|
if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
|
|
|
|
if ( inPt.y === edgeLowPt.y ) {
|
|
|
|
if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ?
|
|
// continue; // no intersection or edgeLowPt => doesn't count !!!
|
|
|
|
} else {
|
|
|
|
var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
|
|
if ( perpEdge === 0 ) return true; // inPt is on contour ?
|
|
if ( perpEdge < 0 ) continue;
|
|
inside = ! inside; // true intersection left of inPt
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// parallel or collinear
|
|
if ( inPt.y !== edgeLowPt.y ) continue; // parallel
|
|
// edge lies on the same horizontal line as inPt
|
|
if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
|
|
( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour !
|
|
// continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return inside;
|
|
|
|
}
|
|
|
|
var isClockWise = ShapeUtils.isClockWise;
|
|
|
|
var subPaths = this.subPaths;
|
|
if ( subPaths.length === 0 ) return [];
|
|
|
|
if ( noHoles === true ) return toShapesNoHoles( subPaths );
|
|
|
|
|
|
var solid, tmpPath, tmpShape, shapes = [];
|
|
|
|
if ( subPaths.length === 1 ) {
|
|
|
|
tmpPath = subPaths[ 0 ];
|
|
tmpShape = new Shape();
|
|
tmpShape.curves = tmpPath.curves;
|
|
shapes.push( tmpShape );
|
|
return shapes;
|
|
|
|
}
|
|
|
|
var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
|
|
holesFirst = isCCW ? ! holesFirst : holesFirst;
|
|
|
|
// console.log("Holes first", holesFirst);
|
|
|
|
var betterShapeHoles = [];
|
|
var newShapes = [];
|
|
var newShapeHoles = [];
|
|
var mainIdx = 0;
|
|
var tmpPoints;
|
|
|
|
newShapes[ mainIdx ] = undefined;
|
|
newShapeHoles[ mainIdx ] = [];
|
|
|
|
for ( var i = 0, l = subPaths.length; i < l; i ++ ) {
|
|
|
|
tmpPath = subPaths[ i ];
|
|
tmpPoints = tmpPath.getPoints();
|
|
solid = isClockWise( tmpPoints );
|
|
solid = isCCW ? ! solid : solid;
|
|
|
|
if ( solid ) {
|
|
|
|
if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
|
|
|
|
newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
|
|
newShapes[ mainIdx ].s.curves = tmpPath.curves;
|
|
|
|
if ( holesFirst ) mainIdx ++;
|
|
newShapeHoles[ mainIdx ] = [];
|
|
|
|
//console.log('cw', i);
|
|
|
|
} else {
|
|
|
|
newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
|
|
|
|
//console.log('ccw', i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// only Holes? -> probably all Shapes with wrong orientation
|
|
if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
|
|
|
|
|
|
if ( newShapes.length > 1 ) {
|
|
|
|
var ambiguous = false;
|
|
var toChange = [];
|
|
|
|
for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
|
|
|
|
betterShapeHoles[ sIdx ] = [];
|
|
|
|
}
|
|
|
|
for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
|
|
|
|
var sho = newShapeHoles[ sIdx ];
|
|
|
|
for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {
|
|
|
|
var ho = sho[ hIdx ];
|
|
var hole_unassigned = true;
|
|
|
|
for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
|
|
|
|
if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
|
|
|
|
if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );
|
|
if ( hole_unassigned ) {
|
|
|
|
hole_unassigned = false;
|
|
betterShapeHoles[ s2Idx ].push( ho );
|
|
|
|
} else {
|
|
|
|
ambiguous = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
if ( hole_unassigned ) {
|
|
|
|
betterShapeHoles[ sIdx ].push( ho );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
// console.log("ambiguous: ", ambiguous);
|
|
if ( toChange.length > 0 ) {
|
|
|
|
// console.log("to change: ", toChange);
|
|
if ( ! ambiguous ) newShapeHoles = betterShapeHoles;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var tmpHoles;
|
|
|
|
for ( var i = 0, il = newShapes.length; i < il; i ++ ) {
|
|
|
|
tmpShape = newShapes[ i ].s;
|
|
shapes.push( tmpShape );
|
|
tmpHoles = newShapeHoles[ i ];
|
|
|
|
for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
|
|
|
|
tmpShape.holes.push( tmpHoles[ j ].h );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//console.log("shape", shapes);
|
|
|
|
return shapes;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author zz85 / http://www.lab4games.net/zz85/blog
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Font( data ) {
|
|
|
|
this.data = data;
|
|
|
|
}
|
|
|
|
Object.assign( Font.prototype, {
|
|
|
|
isFont: true,
|
|
|
|
generateShapes: function ( text, size, divisions ) {
|
|
|
|
function createPaths( text ) {
|
|
|
|
var chars = String( text ).split( '' );
|
|
var scale = size / data.resolution;
|
|
var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
|
|
|
|
var offsetX = 0, offsetY = 0;
|
|
|
|
var paths = [];
|
|
|
|
for ( var i = 0; i < chars.length; i ++ ) {
|
|
|
|
var char = chars[ i ];
|
|
|
|
if ( char === '\n' ) {
|
|
|
|
offsetX = 0;
|
|
offsetY -= line_height;
|
|
|
|
} else {
|
|
|
|
var ret = createPath( char, scale, offsetX, offsetY );
|
|
offsetX += ret.offsetX;
|
|
paths.push( ret.path );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return paths;
|
|
|
|
}
|
|
|
|
function createPath( c, scale, offsetX, offsetY ) {
|
|
|
|
var glyph = data.glyphs[ c ] || data.glyphs[ '?' ];
|
|
|
|
if ( ! glyph ) return;
|
|
|
|
var path = new ShapePath();
|
|
|
|
var pts = [];
|
|
var x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;
|
|
|
|
if ( glyph.o ) {
|
|
|
|
var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
|
|
|
|
for ( var i = 0, l = outline.length; i < l; ) {
|
|
|
|
var action = outline[ i ++ ];
|
|
|
|
switch ( action ) {
|
|
|
|
case 'm': // moveTo
|
|
|
|
x = outline[ i ++ ] * scale + offsetX;
|
|
y = outline[ i ++ ] * scale + offsetY;
|
|
|
|
path.moveTo( x, y );
|
|
|
|
break;
|
|
|
|
case 'l': // lineTo
|
|
|
|
x = outline[ i ++ ] * scale + offsetX;
|
|
y = outline[ i ++ ] * scale + offsetY;
|
|
|
|
path.lineTo( x, y );
|
|
|
|
break;
|
|
|
|
case 'q': // quadraticCurveTo
|
|
|
|
cpx = outline[ i ++ ] * scale + offsetX;
|
|
cpy = outline[ i ++ ] * scale + offsetY;
|
|
cpx1 = outline[ i ++ ] * scale + offsetX;
|
|
cpy1 = outline[ i ++ ] * scale + offsetY;
|
|
|
|
path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
|
|
|
|
laste = pts[ pts.length - 1 ];
|
|
|
|
if ( laste ) {
|
|
|
|
cpx0 = laste.x;
|
|
cpy0 = laste.y;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'b': // bezierCurveTo
|
|
|
|
cpx = outline[ i ++ ] * scale + offsetX;
|
|
cpy = outline[ i ++ ] * scale + offsetY;
|
|
cpx1 = outline[ i ++ ] * scale + offsetX;
|
|
cpy1 = outline[ i ++ ] * scale + offsetY;
|
|
cpx2 = outline[ i ++ ] * scale + offsetX;
|
|
cpy2 = outline[ i ++ ] * scale + offsetY;
|
|
|
|
path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
|
|
|
|
laste = pts[ pts.length - 1 ];
|
|
|
|
if ( laste ) {
|
|
|
|
cpx0 = laste.x;
|
|
cpy0 = laste.y;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { offsetX: glyph.ha * scale, path: path };
|
|
|
|
}
|
|
|
|
//
|
|
|
|
if ( size === undefined ) size = 100;
|
|
if ( divisions === undefined ) divisions = 4;
|
|
|
|
var data = this.data;
|
|
|
|
var paths = createPaths( text );
|
|
var shapes = [];
|
|
|
|
for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
|
|
|
|
Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
|
|
|
|
}
|
|
|
|
return shapes;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function FontLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( FontLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var scope = this;
|
|
|
|
var loader = new FileLoader( this.manager );
|
|
loader.load( url, function ( text ) {
|
|
|
|
var json;
|
|
|
|
try {
|
|
|
|
json = JSON.parse( text );
|
|
|
|
} catch ( e ) {
|
|
|
|
console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
|
|
json = JSON.parse( text.substring( 65, text.length - 2 ) );
|
|
|
|
}
|
|
|
|
var font = scope.parse( json );
|
|
|
|
if ( onLoad ) onLoad( font );
|
|
|
|
}, onProgress, onError );
|
|
|
|
},
|
|
|
|
parse: function ( json ) {
|
|
|
|
return new Font( json );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
var context;
|
|
|
|
var AudioContext = {
|
|
|
|
getContext: function () {
|
|
|
|
if ( context === undefined ) {
|
|
|
|
context = new ( window.AudioContext || window.webkitAudioContext )();
|
|
|
|
}
|
|
|
|
return context;
|
|
|
|
},
|
|
|
|
setContext: function ( value ) {
|
|
|
|
context = value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @author Reece Aaron Lecrivain / http://reecenotes.com/
|
|
*/
|
|
|
|
function AudioLoader( manager ) {
|
|
|
|
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
|
|
|
|
}
|
|
|
|
Object.assign( AudioLoader.prototype, {
|
|
|
|
load: function ( url, onLoad, onProgress, onError ) {
|
|
|
|
var loader = new FileLoader( this.manager );
|
|
loader.setResponseType( 'arraybuffer' );
|
|
loader.load( url, function ( buffer ) {
|
|
|
|
var context = AudioContext.getContext();
|
|
|
|
context.decodeAudioData( buffer, function ( audioBuffer ) {
|
|
|
|
onLoad( audioBuffer );
|
|
|
|
} );
|
|
|
|
}, onProgress, onError );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function StereoCamera() {
|
|
|
|
this.type = 'StereoCamera';
|
|
|
|
this.aspect = 1;
|
|
|
|
this.eyeSep = 0.064;
|
|
|
|
this.cameraL = new PerspectiveCamera();
|
|
this.cameraL.layers.enable( 1 );
|
|
this.cameraL.matrixAutoUpdate = false;
|
|
|
|
this.cameraR = new PerspectiveCamera();
|
|
this.cameraR.layers.enable( 2 );
|
|
this.cameraR.matrixAutoUpdate = false;
|
|
|
|
}
|
|
|
|
Object.assign( StereoCamera.prototype, {
|
|
|
|
update: ( function () {
|
|
|
|
var instance, focus, fov, aspect, near, far, zoom, eyeSep;
|
|
|
|
var eyeRight = new Matrix4();
|
|
var eyeLeft = new Matrix4();
|
|
|
|
return function update( camera ) {
|
|
|
|
var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
|
|
aspect !== camera.aspect * this.aspect || near !== camera.near ||
|
|
far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
|
|
|
|
if ( needsUpdate ) {
|
|
|
|
instance = this;
|
|
focus = camera.focus;
|
|
fov = camera.fov;
|
|
aspect = camera.aspect * this.aspect;
|
|
near = camera.near;
|
|
far = camera.far;
|
|
zoom = camera.zoom;
|
|
|
|
// Off-axis stereoscopic effect based on
|
|
// http://paulbourke.net/stereographics/stereorender/
|
|
|
|
var projectionMatrix = camera.projectionMatrix.clone();
|
|
eyeSep = this.eyeSep / 2;
|
|
var eyeSepOnProjection = eyeSep * near / focus;
|
|
var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
|
|
var xmin, xmax;
|
|
|
|
// translate xOffset
|
|
|
|
eyeLeft.elements[ 12 ] = - eyeSep;
|
|
eyeRight.elements[ 12 ] = eyeSep;
|
|
|
|
// for left eye
|
|
|
|
xmin = - ymax * aspect + eyeSepOnProjection;
|
|
xmax = ymax * aspect + eyeSepOnProjection;
|
|
|
|
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
|
|
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
|
|
|
this.cameraL.projectionMatrix.copy( projectionMatrix );
|
|
|
|
// for right eye
|
|
|
|
xmin = - ymax * aspect - eyeSepOnProjection;
|
|
xmax = ymax * aspect - eyeSepOnProjection;
|
|
|
|
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
|
|
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
|
|
|
this.cameraR.projectionMatrix.copy( projectionMatrix );
|
|
|
|
}
|
|
|
|
this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );
|
|
this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );
|
|
|
|
};
|
|
|
|
} )()
|
|
|
|
} );
|
|
|
|
/**
|
|
* Camera for rendering cube maps
|
|
* - renders scene into axis-aligned cube
|
|
*
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function CubeCamera( near, far, cubeResolution ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'CubeCamera';
|
|
|
|
var fov = 90, aspect = 1;
|
|
|
|
var cameraPX = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraPX.up.set( 0, - 1, 0 );
|
|
cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
|
|
this.add( cameraPX );
|
|
|
|
var cameraNX = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraNX.up.set( 0, - 1, 0 );
|
|
cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
|
|
this.add( cameraNX );
|
|
|
|
var cameraPY = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraPY.up.set( 0, 0, 1 );
|
|
cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
|
|
this.add( cameraPY );
|
|
|
|
var cameraNY = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraNY.up.set( 0, 0, - 1 );
|
|
cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
|
|
this.add( cameraNY );
|
|
|
|
var cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraPZ.up.set( 0, - 1, 0 );
|
|
cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
|
|
this.add( cameraPZ );
|
|
|
|
var cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
|
|
cameraNZ.up.set( 0, - 1, 0 );
|
|
cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
|
|
this.add( cameraNZ );
|
|
|
|
var options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };
|
|
|
|
this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );
|
|
this.renderTarget.texture.name = "CubeCamera";
|
|
|
|
this.updateCubeMap = function ( renderer, scene ) {
|
|
|
|
if ( this.parent === null ) this.updateMatrixWorld();
|
|
|
|
var renderTarget = this.renderTarget;
|
|
var generateMipmaps = renderTarget.texture.generateMipmaps;
|
|
|
|
renderTarget.texture.generateMipmaps = false;
|
|
|
|
renderTarget.activeCubeFace = 0;
|
|
renderer.render( scene, cameraPX, renderTarget );
|
|
|
|
renderTarget.activeCubeFace = 1;
|
|
renderer.render( scene, cameraNX, renderTarget );
|
|
|
|
renderTarget.activeCubeFace = 2;
|
|
renderer.render( scene, cameraPY, renderTarget );
|
|
|
|
renderTarget.activeCubeFace = 3;
|
|
renderer.render( scene, cameraNY, renderTarget );
|
|
|
|
renderTarget.activeCubeFace = 4;
|
|
renderer.render( scene, cameraPZ, renderTarget );
|
|
|
|
renderTarget.texture.generateMipmaps = generateMipmaps;
|
|
|
|
renderTarget.activeCubeFace = 5;
|
|
renderer.render( scene, cameraNZ, renderTarget );
|
|
|
|
renderer.setRenderTarget( null );
|
|
|
|
};
|
|
|
|
}
|
|
|
|
CubeCamera.prototype = Object.create( Object3D.prototype );
|
|
CubeCamera.prototype.constructor = CubeCamera;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function ArrayCamera( array ) {
|
|
|
|
PerspectiveCamera.call( this );
|
|
|
|
this.enabled = false;
|
|
this.cameras = array || [];
|
|
|
|
}
|
|
|
|
ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
|
|
|
|
constructor: ArrayCamera,
|
|
|
|
isArrayCamera: true
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function AudioListener() {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'AudioListener';
|
|
|
|
this.context = AudioContext.getContext();
|
|
|
|
this.gain = this.context.createGain();
|
|
this.gain.connect( this.context.destination );
|
|
|
|
this.filter = null;
|
|
|
|
}
|
|
|
|
AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: AudioListener,
|
|
|
|
getInput: function () {
|
|
|
|
return this.gain;
|
|
|
|
},
|
|
|
|
removeFilter: function ( ) {
|
|
|
|
if ( this.filter !== null ) {
|
|
|
|
this.gain.disconnect( this.filter );
|
|
this.filter.disconnect( this.context.destination );
|
|
this.gain.connect( this.context.destination );
|
|
this.filter = null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getFilter: function () {
|
|
|
|
return this.filter;
|
|
|
|
},
|
|
|
|
setFilter: function ( value ) {
|
|
|
|
if ( this.filter !== null ) {
|
|
|
|
this.gain.disconnect( this.filter );
|
|
this.filter.disconnect( this.context.destination );
|
|
|
|
} else {
|
|
|
|
this.gain.disconnect( this.context.destination );
|
|
|
|
}
|
|
|
|
this.filter = value;
|
|
this.gain.connect( this.filter );
|
|
this.filter.connect( this.context.destination );
|
|
|
|
},
|
|
|
|
getMasterVolume: function () {
|
|
|
|
return this.gain.gain.value;
|
|
|
|
},
|
|
|
|
setMasterVolume: function ( value ) {
|
|
|
|
this.gain.gain.value = value;
|
|
|
|
},
|
|
|
|
updateMatrixWorld: ( function () {
|
|
|
|
var position = new Vector3();
|
|
var quaternion = new Quaternion();
|
|
var scale = new Vector3();
|
|
|
|
var orientation = new Vector3();
|
|
|
|
return function updateMatrixWorld( force ) {
|
|
|
|
Object3D.prototype.updateMatrixWorld.call( this, force );
|
|
|
|
var listener = this.context.listener;
|
|
var up = this.up;
|
|
|
|
this.matrixWorld.decompose( position, quaternion, scale );
|
|
|
|
orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );
|
|
|
|
if ( listener.positionX ) {
|
|
|
|
listener.positionX.setValueAtTime( position.x, this.context.currentTime );
|
|
listener.positionY.setValueAtTime( position.y, this.context.currentTime );
|
|
listener.positionZ.setValueAtTime( position.z, this.context.currentTime );
|
|
listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );
|
|
listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );
|
|
listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );
|
|
listener.upX.setValueAtTime( up.x, this.context.currentTime );
|
|
listener.upY.setValueAtTime( up.y, this.context.currentTime );
|
|
listener.upZ.setValueAtTime( up.z, this.context.currentTime );
|
|
|
|
} else {
|
|
|
|
listener.setPosition( position.x, position.y, position.z );
|
|
listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} )()
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Reece Aaron Lecrivain / http://reecenotes.com/
|
|
*/
|
|
|
|
function Audio( listener ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.type = 'Audio';
|
|
|
|
this.context = listener.context;
|
|
|
|
this.gain = this.context.createGain();
|
|
this.gain.connect( listener.getInput() );
|
|
|
|
this.autoplay = false;
|
|
|
|
this.buffer = null;
|
|
this.loop = false;
|
|
this.startTime = 0;
|
|
this.playbackRate = 1;
|
|
this.isPlaying = false;
|
|
this.hasPlaybackControl = true;
|
|
this.sourceType = 'empty';
|
|
|
|
this.filters = [];
|
|
|
|
}
|
|
|
|
Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
|
|
|
|
constructor: Audio,
|
|
|
|
getOutput: function () {
|
|
|
|
return this.gain;
|
|
|
|
},
|
|
|
|
setNodeSource: function ( audioNode ) {
|
|
|
|
this.hasPlaybackControl = false;
|
|
this.sourceType = 'audioNode';
|
|
this.source = audioNode;
|
|
this.connect();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setBuffer: function ( audioBuffer ) {
|
|
|
|
this.buffer = audioBuffer;
|
|
this.sourceType = 'buffer';
|
|
|
|
if ( this.autoplay ) this.play();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
play: function () {
|
|
|
|
if ( this.isPlaying === true ) {
|
|
|
|
console.warn( 'THREE.Audio: Audio is already playing.' );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return;
|
|
|
|
}
|
|
|
|
var source = this.context.createBufferSource();
|
|
|
|
source.buffer = this.buffer;
|
|
source.loop = this.loop;
|
|
source.onended = this.onEnded.bind( this );
|
|
source.playbackRate.setValueAtTime( this.playbackRate, this.startTime );
|
|
source.start( 0, this.startTime );
|
|
|
|
this.isPlaying = true;
|
|
|
|
this.source = source;
|
|
|
|
return this.connect();
|
|
|
|
},
|
|
|
|
pause: function () {
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return;
|
|
|
|
}
|
|
|
|
this.source.stop();
|
|
this.startTime = this.context.currentTime;
|
|
this.isPlaying = false;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
stop: function () {
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return;
|
|
|
|
}
|
|
|
|
this.source.stop();
|
|
this.startTime = 0;
|
|
this.isPlaying = false;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
connect: function () {
|
|
|
|
if ( this.filters.length > 0 ) {
|
|
|
|
this.source.connect( this.filters[ 0 ] );
|
|
|
|
for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
|
|
|
|
this.filters[ i - 1 ].connect( this.filters[ i ] );
|
|
|
|
}
|
|
|
|
this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
|
|
|
|
} else {
|
|
|
|
this.source.connect( this.getOutput() );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
disconnect: function () {
|
|
|
|
if ( this.filters.length > 0 ) {
|
|
|
|
this.source.disconnect( this.filters[ 0 ] );
|
|
|
|
for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
|
|
|
|
this.filters[ i - 1 ].disconnect( this.filters[ i ] );
|
|
|
|
}
|
|
|
|
this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
|
|
|
|
} else {
|
|
|
|
this.source.disconnect( this.getOutput() );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getFilters: function () {
|
|
|
|
return this.filters;
|
|
|
|
},
|
|
|
|
setFilters: function ( value ) {
|
|
|
|
if ( ! value ) value = [];
|
|
|
|
if ( this.isPlaying === true ) {
|
|
|
|
this.disconnect();
|
|
this.filters = value;
|
|
this.connect();
|
|
|
|
} else {
|
|
|
|
this.filters = value;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getFilter: function () {
|
|
|
|
return this.getFilters()[ 0 ];
|
|
|
|
},
|
|
|
|
setFilter: function ( filter ) {
|
|
|
|
return this.setFilters( filter ? [ filter ] : [] );
|
|
|
|
},
|
|
|
|
setPlaybackRate: function ( value ) {
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return;
|
|
|
|
}
|
|
|
|
this.playbackRate = value;
|
|
|
|
if ( this.isPlaying === true ) {
|
|
|
|
this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getPlaybackRate: function () {
|
|
|
|
return this.playbackRate;
|
|
|
|
},
|
|
|
|
onEnded: function () {
|
|
|
|
this.isPlaying = false;
|
|
|
|
},
|
|
|
|
getLoop: function () {
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return false;
|
|
|
|
}
|
|
|
|
return this.loop;
|
|
|
|
},
|
|
|
|
setLoop: function ( value ) {
|
|
|
|
if ( this.hasPlaybackControl === false ) {
|
|
|
|
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
|
return;
|
|
|
|
}
|
|
|
|
this.loop = value;
|
|
|
|
if ( this.isPlaying === true ) {
|
|
|
|
this.source.loop = this.loop;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getVolume: function () {
|
|
|
|
return this.gain.gain.value;
|
|
|
|
},
|
|
|
|
setVolume: function ( value ) {
|
|
|
|
this.gain.gain.value = value;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function PositionalAudio( listener ) {
|
|
|
|
Audio.call( this, listener );
|
|
|
|
this.panner = this.context.createPanner();
|
|
this.panner.connect( this.gain );
|
|
|
|
}
|
|
|
|
PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
|
|
|
|
constructor: PositionalAudio,
|
|
|
|
getOutput: function () {
|
|
|
|
return this.panner;
|
|
|
|
},
|
|
|
|
getRefDistance: function () {
|
|
|
|
return this.panner.refDistance;
|
|
|
|
},
|
|
|
|
setRefDistance: function ( value ) {
|
|
|
|
this.panner.refDistance = value;
|
|
|
|
},
|
|
|
|
getRolloffFactor: function () {
|
|
|
|
return this.panner.rolloffFactor;
|
|
|
|
},
|
|
|
|
setRolloffFactor: function ( value ) {
|
|
|
|
this.panner.rolloffFactor = value;
|
|
|
|
},
|
|
|
|
getDistanceModel: function () {
|
|
|
|
return this.panner.distanceModel;
|
|
|
|
},
|
|
|
|
setDistanceModel: function ( value ) {
|
|
|
|
this.panner.distanceModel = value;
|
|
|
|
},
|
|
|
|
getMaxDistance: function () {
|
|
|
|
return this.panner.maxDistance;
|
|
|
|
},
|
|
|
|
setMaxDistance: function ( value ) {
|
|
|
|
this.panner.maxDistance = value;
|
|
|
|
},
|
|
|
|
updateMatrixWorld: ( function () {
|
|
|
|
var position = new Vector3();
|
|
|
|
return function updateMatrixWorld( force ) {
|
|
|
|
Object3D.prototype.updateMatrixWorld.call( this, force );
|
|
|
|
position.setFromMatrixPosition( this.matrixWorld );
|
|
|
|
this.panner.setPosition( position.x, position.y, position.z );
|
|
|
|
};
|
|
|
|
} )()
|
|
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function AudioAnalyser( audio, fftSize ) {
|
|
|
|
this.analyser = audio.context.createAnalyser();
|
|
this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;
|
|
|
|
this.data = new Uint8Array( this.analyser.frequencyBinCount );
|
|
|
|
audio.getOutput().connect( this.analyser );
|
|
|
|
}
|
|
|
|
Object.assign( AudioAnalyser.prototype, {
|
|
|
|
getFrequencyData: function () {
|
|
|
|
this.analyser.getByteFrequencyData( this.data );
|
|
|
|
return this.data;
|
|
|
|
},
|
|
|
|
getAverageFrequency: function () {
|
|
|
|
var value = 0, data = this.getFrequencyData();
|
|
|
|
for ( var i = 0; i < data.length; i ++ ) {
|
|
|
|
value += data[ i ];
|
|
|
|
}
|
|
|
|
return value / data.length;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* Buffered scene graph property that allows weighted accumulation.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function PropertyMixer( binding, typeName, valueSize ) {
|
|
|
|
this.binding = binding;
|
|
this.valueSize = valueSize;
|
|
|
|
var bufferType = Float64Array,
|
|
mixFunction;
|
|
|
|
switch ( typeName ) {
|
|
|
|
case 'quaternion':
|
|
mixFunction = this._slerp;
|
|
break;
|
|
|
|
case 'string':
|
|
case 'bool':
|
|
bufferType = Array;
|
|
mixFunction = this._select;
|
|
break;
|
|
|
|
default:
|
|
mixFunction = this._lerp;
|
|
|
|
}
|
|
|
|
this.buffer = new bufferType( valueSize * 4 );
|
|
// layout: [ incoming | accu0 | accu1 | orig ]
|
|
//
|
|
// interpolators can use .buffer as their .result
|
|
// the data then goes to 'incoming'
|
|
//
|
|
// 'accu0' and 'accu1' are used frame-interleaved for
|
|
// the cumulative result and are compared to detect
|
|
// changes
|
|
//
|
|
// 'orig' stores the original state of the property
|
|
|
|
this._mixBufferRegion = mixFunction;
|
|
|
|
this.cumulativeWeight = 0;
|
|
|
|
this.useCount = 0;
|
|
this.referenceCount = 0;
|
|
|
|
}
|
|
|
|
Object.assign( PropertyMixer.prototype, {
|
|
|
|
// accumulate data in the 'incoming' region into 'accu<i>'
|
|
accumulate: function ( accuIndex, weight ) {
|
|
|
|
// note: happily accumulating nothing when weight = 0, the caller knows
|
|
// the weight and shouldn't have made the call in the first place
|
|
|
|
var buffer = this.buffer,
|
|
stride = this.valueSize,
|
|
offset = accuIndex * stride + stride,
|
|
|
|
currentWeight = this.cumulativeWeight;
|
|
|
|
if ( currentWeight === 0 ) {
|
|
|
|
// accuN := incoming * weight
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
buffer[ offset + i ] = buffer[ i ];
|
|
|
|
}
|
|
|
|
currentWeight = weight;
|
|
|
|
} else {
|
|
|
|
// accuN := accuN + incoming * weight
|
|
|
|
currentWeight += weight;
|
|
var mix = weight / currentWeight;
|
|
this._mixBufferRegion( buffer, offset, 0, mix, stride );
|
|
|
|
}
|
|
|
|
this.cumulativeWeight = currentWeight;
|
|
|
|
},
|
|
|
|
// apply the state of 'accu<i>' to the binding when accus differ
|
|
apply: function ( accuIndex ) {
|
|
|
|
var stride = this.valueSize,
|
|
buffer = this.buffer,
|
|
offset = accuIndex * stride + stride,
|
|
|
|
weight = this.cumulativeWeight,
|
|
|
|
binding = this.binding;
|
|
|
|
this.cumulativeWeight = 0;
|
|
|
|
if ( weight < 1 ) {
|
|
|
|
// accuN := accuN + original * ( 1 - cumulativeWeight )
|
|
|
|
var originalValueOffset = stride * 3;
|
|
|
|
this._mixBufferRegion(
|
|
buffer, offset, originalValueOffset, 1 - weight, stride );
|
|
|
|
}
|
|
|
|
for ( var i = stride, e = stride + stride; i !== e; ++ i ) {
|
|
|
|
if ( buffer[ i ] !== buffer[ i + stride ] ) {
|
|
|
|
// value has changed -> update scene graph
|
|
|
|
binding.setValue( buffer, offset );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// remember the state of the bound property and copy it to both accus
|
|
saveOriginalState: function () {
|
|
|
|
var binding = this.binding;
|
|
|
|
var buffer = this.buffer,
|
|
stride = this.valueSize,
|
|
|
|
originalValueOffset = stride * 3;
|
|
|
|
binding.getValue( buffer, originalValueOffset );
|
|
|
|
// accu[0..1] := orig -- initially detect changes against the original
|
|
for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {
|
|
|
|
buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
|
|
|
|
}
|
|
|
|
this.cumulativeWeight = 0;
|
|
|
|
},
|
|
|
|
// apply the state previously taken via 'saveOriginalState' to the binding
|
|
restoreOriginalState: function () {
|
|
|
|
var originalValueOffset = this.valueSize * 3;
|
|
this.binding.setValue( this.buffer, originalValueOffset );
|
|
|
|
},
|
|
|
|
|
|
// mix functions
|
|
|
|
_select: function ( buffer, dstOffset, srcOffset, t, stride ) {
|
|
|
|
if ( t >= 0.5 ) {
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_slerp: function ( buffer, dstOffset, srcOffset, t ) {
|
|
|
|
Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
|
|
|
|
},
|
|
|
|
_lerp: function ( buffer, dstOffset, srcOffset, t, stride ) {
|
|
|
|
var s = 1 - t;
|
|
|
|
for ( var i = 0; i !== stride; ++ i ) {
|
|
|
|
var j = dstOffset + i;
|
|
|
|
buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A reference to a real property in the scene graph.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function Composite( targetGroup, path, optionalParsedPath ) {
|
|
|
|
var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
|
|
|
|
this._targetGroup = targetGroup;
|
|
this._bindings = targetGroup.subscribe_( path, parsedPath );
|
|
|
|
}
|
|
|
|
Object.assign( Composite.prototype, {
|
|
|
|
getValue: function ( array, offset ) {
|
|
|
|
this.bind(); // bind all binding
|
|
|
|
var firstValidIndex = this._targetGroup.nCachedObjects_,
|
|
binding = this._bindings[ firstValidIndex ];
|
|
|
|
// and only call .getValue on the first
|
|
if ( binding !== undefined ) binding.getValue( array, offset );
|
|
|
|
},
|
|
|
|
setValue: function ( array, offset ) {
|
|
|
|
var bindings = this._bindings;
|
|
|
|
for ( var i = this._targetGroup.nCachedObjects_,
|
|
n = bindings.length; i !== n; ++ i ) {
|
|
|
|
bindings[ i ].setValue( array, offset );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
bind: function () {
|
|
|
|
var bindings = this._bindings;
|
|
|
|
for ( var i = this._targetGroup.nCachedObjects_,
|
|
n = bindings.length; i !== n; ++ i ) {
|
|
|
|
bindings[ i ].bind();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
unbind: function () {
|
|
|
|
var bindings = this._bindings;
|
|
|
|
for ( var i = this._targetGroup.nCachedObjects_,
|
|
n = bindings.length; i !== n; ++ i ) {
|
|
|
|
bindings[ i ].unbind();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
function PropertyBinding( rootNode, path, parsedPath ) {
|
|
|
|
this.path = path;
|
|
this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
|
|
|
|
this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;
|
|
|
|
this.rootNode = rootNode;
|
|
|
|
}
|
|
|
|
Object.assign( PropertyBinding, {
|
|
|
|
Composite: Composite,
|
|
|
|
create: function ( root, path, parsedPath ) {
|
|
|
|
if ( ! ( root && root.isAnimationObjectGroup ) ) {
|
|
|
|
return new PropertyBinding( root, path, parsedPath );
|
|
|
|
} else {
|
|
|
|
return new PropertyBinding.Composite( root, path, parsedPath );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
parseTrackName: function () {
|
|
|
|
// Parent directories, delimited by '/' or ':'. Currently unused, but must
|
|
// be matched to parse the rest of the track name.
|
|
var directoryRe = /((?:[\w-]+[\/:])*)/;
|
|
|
|
// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
|
|
var nodeRe = /([\w-\.]+)?/;
|
|
|
|
// Object on target node, and accessor. Name may contain only word
|
|
// characters. Accessor may contain any character except closing bracket.
|
|
var objectRe = /(?:\.([\w-]+)(?:\[(.+)\])?)?/;
|
|
|
|
// Property and accessor. May contain only word characters. Accessor may
|
|
// contain any non-bracket characters.
|
|
var propertyRe = /\.([\w-]+)(?:\[(.+)\])?/;
|
|
|
|
var trackRe = new RegExp(''
|
|
+ '^'
|
|
+ directoryRe.source
|
|
+ nodeRe.source
|
|
+ objectRe.source
|
|
+ propertyRe.source
|
|
+ '$'
|
|
);
|
|
|
|
var supportedObjectNames = [ 'material', 'materials', 'bones' ];
|
|
|
|
return function ( trackName ) {
|
|
|
|
var matches = trackRe.exec( trackName );
|
|
|
|
if ( ! matches ) {
|
|
|
|
throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
|
|
|
|
}
|
|
|
|
var results = {
|
|
// directoryName: matches[ 1 ], // (tschw) currently unused
|
|
nodeName: matches[ 2 ],
|
|
objectName: matches[ 3 ],
|
|
objectIndex: matches[ 4 ],
|
|
propertyName: matches[ 5 ], // required
|
|
propertyIndex: matches[ 6 ]
|
|
};
|
|
|
|
var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
|
|
|
|
if ( lastDot !== undefined && lastDot !== -1 ) {
|
|
|
|
var objectName = results.nodeName.substring( lastDot + 1 );
|
|
|
|
// Object names must be checked against a whitelist. Otherwise, there
|
|
// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
|
|
// 'bar' could be the objectName, or part of a nodeName (which can
|
|
// include '.' characters).
|
|
if ( supportedObjectNames.indexOf( objectName ) !== -1 ) {
|
|
|
|
results.nodeName = results.nodeName.substring( 0, lastDot );
|
|
results.objectName = objectName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( results.propertyName === null || results.propertyName.length === 0 ) {
|
|
|
|
throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
};
|
|
|
|
}(),
|
|
|
|
findNode: function ( root, nodeName ) {
|
|
|
|
if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
// search into skeleton bones.
|
|
if ( root.skeleton ) {
|
|
|
|
var searchSkeleton = function ( skeleton ) {
|
|
|
|
for ( var i = 0; i < skeleton.bones.length; i ++ ) {
|
|
|
|
var bone = skeleton.bones[ i ];
|
|
|
|
if ( bone.name === nodeName ) {
|
|
|
|
return bone;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
var bone = searchSkeleton( root.skeleton );
|
|
|
|
if ( bone ) {
|
|
|
|
return bone;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// search into node subtree.
|
|
if ( root.children ) {
|
|
|
|
var searchNodeSubtree = function ( children ) {
|
|
|
|
for ( var i = 0; i < children.length; i ++ ) {
|
|
|
|
var childNode = children[ i ];
|
|
|
|
if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
|
|
|
|
return childNode;
|
|
|
|
}
|
|
|
|
var result = searchNodeSubtree( childNode.children );
|
|
|
|
if ( result ) return result;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
var subTreeNode = searchNodeSubtree( root.children );
|
|
|
|
if ( subTreeNode ) {
|
|
|
|
return subTreeNode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( PropertyBinding.prototype, { // prototype, continued
|
|
|
|
// these are used to "bind" a nonexistent property
|
|
_getValue_unavailable: function () {},
|
|
_setValue_unavailable: function () {},
|
|
|
|
BindingType: {
|
|
Direct: 0,
|
|
EntireArray: 1,
|
|
ArrayElement: 2,
|
|
HasFromToArray: 3
|
|
},
|
|
|
|
Versioning: {
|
|
None: 0,
|
|
NeedsUpdate: 1,
|
|
MatrixWorldNeedsUpdate: 2
|
|
},
|
|
|
|
GetterByBindingType: [
|
|
|
|
function getValue_direct( buffer, offset ) {
|
|
|
|
buffer[ offset ] = this.node[ this.propertyName ];
|
|
|
|
},
|
|
|
|
function getValue_array( buffer, offset ) {
|
|
|
|
var source = this.resolvedProperty;
|
|
|
|
for ( var i = 0, n = source.length; i !== n; ++ i ) {
|
|
|
|
buffer[ offset ++ ] = source[ i ];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function getValue_arrayElement( buffer, offset ) {
|
|
|
|
buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
|
|
|
|
},
|
|
|
|
function getValue_toArray( buffer, offset ) {
|
|
|
|
this.resolvedProperty.toArray( buffer, offset );
|
|
|
|
}
|
|
|
|
],
|
|
|
|
SetterByBindingTypeAndVersioning: [
|
|
|
|
[
|
|
// Direct
|
|
|
|
function setValue_direct( buffer, offset ) {
|
|
|
|
this.node[ this.propertyName ] = buffer[ offset ];
|
|
|
|
},
|
|
|
|
function setValue_direct_setNeedsUpdate( buffer, offset ) {
|
|
|
|
this.node[ this.propertyName ] = buffer[ offset ];
|
|
this.targetObject.needsUpdate = true;
|
|
|
|
},
|
|
|
|
function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
|
|
|
this.node[ this.propertyName ] = buffer[ offset ];
|
|
this.targetObject.matrixWorldNeedsUpdate = true;
|
|
|
|
}
|
|
|
|
], [
|
|
|
|
// EntireArray
|
|
|
|
function setValue_array( buffer, offset ) {
|
|
|
|
var dest = this.resolvedProperty;
|
|
|
|
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
|
|
|
|
dest[ i ] = buffer[ offset ++ ];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
function setValue_array_setNeedsUpdate( buffer, offset ) {
|
|
|
|
var dest = this.resolvedProperty;
|
|
|
|
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
|
|
|
|
dest[ i ] = buffer[ offset ++ ];
|
|
|
|
}
|
|
|
|
this.targetObject.needsUpdate = true;
|
|
|
|
},
|
|
|
|
function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
|
|
|
var dest = this.resolvedProperty;
|
|
|
|
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
|
|
|
|
dest[ i ] = buffer[ offset ++ ];
|
|
|
|
}
|
|
|
|
this.targetObject.matrixWorldNeedsUpdate = true;
|
|
|
|
}
|
|
|
|
], [
|
|
|
|
// ArrayElement
|
|
|
|
function setValue_arrayElement( buffer, offset ) {
|
|
|
|
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
|
|
|
},
|
|
|
|
function setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
|
|
|
|
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
|
this.targetObject.needsUpdate = true;
|
|
|
|
},
|
|
|
|
function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
|
|
|
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
|
this.targetObject.matrixWorldNeedsUpdate = true;
|
|
|
|
}
|
|
|
|
], [
|
|
|
|
// HasToFromArray
|
|
|
|
function setValue_fromArray( buffer, offset ) {
|
|
|
|
this.resolvedProperty.fromArray( buffer, offset );
|
|
|
|
},
|
|
|
|
function setValue_fromArray_setNeedsUpdate( buffer, offset ) {
|
|
|
|
this.resolvedProperty.fromArray( buffer, offset );
|
|
this.targetObject.needsUpdate = true;
|
|
|
|
},
|
|
|
|
function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
|
|
|
this.resolvedProperty.fromArray( buffer, offset );
|
|
this.targetObject.matrixWorldNeedsUpdate = true;
|
|
|
|
}
|
|
|
|
]
|
|
|
|
],
|
|
|
|
getValue: function getValue_unbound( targetArray, offset ) {
|
|
|
|
this.bind();
|
|
this.getValue( targetArray, offset );
|
|
|
|
// Note: This class uses a State pattern on a per-method basis:
|
|
// 'bind' sets 'this.getValue' / 'setValue' and shadows the
|
|
// prototype version of these methods with one that represents
|
|
// the bound state. When the property is not found, the methods
|
|
// become no-ops.
|
|
|
|
},
|
|
|
|
setValue: function getValue_unbound( sourceArray, offset ) {
|
|
|
|
this.bind();
|
|
this.setValue( sourceArray, offset );
|
|
|
|
},
|
|
|
|
// create getter / setter pair for a property in the scene graph
|
|
bind: function () {
|
|
|
|
var targetObject = this.node,
|
|
parsedPath = this.parsedPath,
|
|
|
|
objectName = parsedPath.objectName,
|
|
propertyName = parsedPath.propertyName,
|
|
propertyIndex = parsedPath.propertyIndex;
|
|
|
|
if ( ! targetObject ) {
|
|
|
|
targetObject = PropertyBinding.findNode(
|
|
this.rootNode, parsedPath.nodeName ) || this.rootNode;
|
|
|
|
this.node = targetObject;
|
|
|
|
}
|
|
|
|
// set fail state so we can just 'return' on error
|
|
this.getValue = this._getValue_unavailable;
|
|
this.setValue = this._setValue_unavailable;
|
|
|
|
// ensure there is a value node
|
|
if ( ! targetObject ) {
|
|
|
|
console.error( " trying to update node for track: " + this.path + " but it wasn't found." );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( objectName ) {
|
|
|
|
var objectIndex = parsedPath.objectIndex;
|
|
|
|
// special cases were we need to reach deeper into the hierarchy to get the face materials....
|
|
switch ( objectName ) {
|
|
|
|
case 'materials':
|
|
|
|
if ( ! targetObject.material ) {
|
|
|
|
console.error( ' can not bind to material as node does not have a material', this );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( ! targetObject.material.materials ) {
|
|
|
|
console.error( ' can not bind to material.materials as node.material does not have a materials array', this );
|
|
return;
|
|
|
|
}
|
|
|
|
targetObject = targetObject.material.materials;
|
|
|
|
break;
|
|
|
|
case 'bones':
|
|
|
|
if ( ! targetObject.skeleton ) {
|
|
|
|
console.error( ' can not bind to bones as node does not have a skeleton', this );
|
|
return;
|
|
|
|
}
|
|
|
|
// potential future optimization: skip this if propertyIndex is already an integer
|
|
// and convert the integer string to a true integer.
|
|
|
|
targetObject = targetObject.skeleton.bones;
|
|
|
|
// support resolving morphTarget names into indices.
|
|
for ( var i = 0; i < targetObject.length; i ++ ) {
|
|
|
|
if ( targetObject[ i ].name === objectIndex ) {
|
|
|
|
objectIndex = i;
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ( targetObject[ objectName ] === undefined ) {
|
|
|
|
console.error( ' can not bind to objectName of node, undefined', this );
|
|
return;
|
|
|
|
}
|
|
|
|
targetObject = targetObject[ objectName ];
|
|
|
|
}
|
|
|
|
|
|
if ( objectIndex !== undefined ) {
|
|
|
|
if ( targetObject[ objectIndex ] === undefined ) {
|
|
|
|
console.error( " trying to bind to objectIndex of objectName, but is undefined:", this, targetObject );
|
|
return;
|
|
|
|
}
|
|
|
|
targetObject = targetObject[ objectIndex ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// resolve property
|
|
var nodeProperty = targetObject[ propertyName ];
|
|
|
|
if ( nodeProperty === undefined ) {
|
|
|
|
var nodeName = parsedPath.nodeName;
|
|
|
|
console.error( " trying to update property for track: " + nodeName +
|
|
'.' + propertyName + " but it wasn't found.", targetObject );
|
|
return;
|
|
|
|
}
|
|
|
|
// determine versioning scheme
|
|
var versioning = this.Versioning.None;
|
|
|
|
if ( targetObject.needsUpdate !== undefined ) { // material
|
|
|
|
versioning = this.Versioning.NeedsUpdate;
|
|
this.targetObject = targetObject;
|
|
|
|
} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform
|
|
|
|
versioning = this.Versioning.MatrixWorldNeedsUpdate;
|
|
this.targetObject = targetObject;
|
|
|
|
}
|
|
|
|
// determine how the property gets bound
|
|
var bindingType = this.BindingType.Direct;
|
|
|
|
if ( propertyIndex !== undefined ) {
|
|
|
|
// access a sub element of the property array (only primitives are supported right now)
|
|
|
|
if ( propertyName === "morphTargetInfluences" ) {
|
|
|
|
// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
|
|
|
|
// support resolving morphTarget names into indices.
|
|
if ( ! targetObject.geometry ) {
|
|
|
|
console.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );
|
|
return;
|
|
|
|
}
|
|
|
|
if ( ! targetObject.geometry.morphTargets ) {
|
|
|
|
console.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );
|
|
return;
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {
|
|
|
|
if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {
|
|
|
|
propertyIndex = i;
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bindingType = this.BindingType.ArrayElement;
|
|
|
|
this.resolvedProperty = nodeProperty;
|
|
this.propertyIndex = propertyIndex;
|
|
|
|
} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
|
|
|
|
// must use copy for Object3D.Euler/Quaternion
|
|
|
|
bindingType = this.BindingType.HasFromToArray;
|
|
|
|
this.resolvedProperty = nodeProperty;
|
|
|
|
} else if ( Array.isArray( nodeProperty ) ) {
|
|
|
|
bindingType = this.BindingType.EntireArray;
|
|
|
|
this.resolvedProperty = nodeProperty;
|
|
|
|
} else {
|
|
|
|
this.propertyName = propertyName;
|
|
|
|
}
|
|
|
|
// select getter / setter
|
|
this.getValue = this.GetterByBindingType[ bindingType ];
|
|
this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
|
|
|
|
},
|
|
|
|
unbind: function () {
|
|
|
|
this.node = null;
|
|
|
|
// back to the prototype version of getValue / setValue
|
|
// note: avoiding to mutate the shape of 'this' via 'delete'
|
|
this.getValue = this._getValue_unbound;
|
|
this.setValue = this._setValue_unbound;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
//!\ DECLARE ALIAS AFTER assign prototype !
|
|
Object.assign( PropertyBinding.prototype, {
|
|
|
|
// initial state of these methods that calls 'bind'
|
|
_getValue_unbound: PropertyBinding.prototype.getValue,
|
|
_setValue_unbound: PropertyBinding.prototype.setValue,
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* A group of objects that receives a shared animation state.
|
|
*
|
|
* Usage:
|
|
*
|
|
* - Add objects you would otherwise pass as 'root' to the
|
|
* constructor or the .clipAction method of AnimationMixer.
|
|
*
|
|
* - Instead pass this object as 'root'.
|
|
*
|
|
* - You can also add and remove objects later when the mixer
|
|
* is running.
|
|
*
|
|
* Note:
|
|
*
|
|
* Objects of this class appear as one object to the mixer,
|
|
* so cache control of the individual objects must be done
|
|
* on the group.
|
|
*
|
|
* Limitation:
|
|
*
|
|
* - The animated properties must be compatible among the
|
|
* all objects in the group.
|
|
*
|
|
* - A single property can either be controlled through a
|
|
* target group or directly, but not both.
|
|
*
|
|
* @author tschw
|
|
*/
|
|
|
|
function AnimationObjectGroup( var_args ) {
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
// cached objects followed by the active ones
|
|
this._objects = Array.prototype.slice.call( arguments );
|
|
|
|
this.nCachedObjects_ = 0; // threshold
|
|
// note: read by PropertyBinding.Composite
|
|
|
|
var indices = {};
|
|
this._indicesByUUID = indices; // for bookkeeping
|
|
|
|
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
|
|
|
|
indices[ arguments[ i ].uuid ] = i;
|
|
|
|
}
|
|
|
|
this._paths = []; // inside: string
|
|
this._parsedPaths = []; // inside: { we don't care, here }
|
|
this._bindings = []; // inside: Array< PropertyBinding >
|
|
this._bindingsIndicesByPath = {}; // inside: indices in these arrays
|
|
|
|
var scope = this;
|
|
|
|
this.stats = {
|
|
|
|
objects: {
|
|
get total() { return scope._objects.length; },
|
|
get inUse() { return this.total - scope.nCachedObjects_; }
|
|
},
|
|
|
|
get bindingsPerObject() { return scope._bindings.length; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
Object.assign( AnimationObjectGroup.prototype, {
|
|
|
|
isAnimationObjectGroup: true,
|
|
|
|
add: function( var_args ) {
|
|
|
|
var objects = this._objects,
|
|
nObjects = objects.length,
|
|
nCachedObjects = this.nCachedObjects_,
|
|
indicesByUUID = this._indicesByUUID,
|
|
paths = this._paths,
|
|
parsedPaths = this._parsedPaths,
|
|
bindings = this._bindings,
|
|
nBindings = bindings.length;
|
|
|
|
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
|
|
|
|
var object = arguments[ i ],
|
|
uuid = object.uuid,
|
|
index = indicesByUUID[ uuid ],
|
|
knownObject = undefined;
|
|
|
|
if ( index === undefined ) {
|
|
|
|
// unknown object -> add it to the ACTIVE region
|
|
|
|
index = nObjects ++;
|
|
indicesByUUID[ uuid ] = index;
|
|
objects.push( object );
|
|
|
|
// accounting is done, now do the same for all bindings
|
|
|
|
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
|
|
|
|
bindings[ j ].push(
|
|
new PropertyBinding(
|
|
object, paths[ j ], parsedPaths[ j ] ) );
|
|
|
|
}
|
|
|
|
} else if ( index < nCachedObjects ) {
|
|
|
|
knownObject = objects[ index ];
|
|
|
|
// move existing object to the ACTIVE region
|
|
|
|
var firstActiveIndex = -- nCachedObjects,
|
|
lastCachedObject = objects[ firstActiveIndex ];
|
|
|
|
indicesByUUID[ lastCachedObject.uuid ] = index;
|
|
objects[ index ] = lastCachedObject;
|
|
|
|
indicesByUUID[ uuid ] = firstActiveIndex;
|
|
objects[ firstActiveIndex ] = object;
|
|
|
|
// accounting is done, now do the same for all bindings
|
|
|
|
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
|
|
|
|
var bindingsForPath = bindings[ j ],
|
|
lastCached = bindingsForPath[ firstActiveIndex ],
|
|
binding = bindingsForPath[ index ];
|
|
|
|
bindingsForPath[ index ] = lastCached;
|
|
|
|
if ( binding === undefined ) {
|
|
|
|
// since we do not bother to create new bindings
|
|
// for objects that are cached, the binding may
|
|
// or may not exist
|
|
|
|
binding = new PropertyBinding(
|
|
object, paths[ j ], parsedPaths[ j ] );
|
|
|
|
}
|
|
|
|
bindingsForPath[ firstActiveIndex ] = binding;
|
|
|
|
}
|
|
|
|
} else if ( objects[ index ] !== knownObject ) {
|
|
|
|
console.error( "Different objects with the same UUID " +
|
|
"detected. Clean the caches or recreate your " +
|
|
"infrastructure when reloading scenes..." );
|
|
|
|
} // else the object is already where we want it to be
|
|
|
|
} // for arguments
|
|
|
|
this.nCachedObjects_ = nCachedObjects;
|
|
|
|
},
|
|
|
|
remove: function( var_args ) {
|
|
|
|
var objects = this._objects,
|
|
nCachedObjects = this.nCachedObjects_,
|
|
indicesByUUID = this._indicesByUUID,
|
|
bindings = this._bindings,
|
|
nBindings = bindings.length;
|
|
|
|
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
|
|
|
|
var object = arguments[ i ],
|
|
uuid = object.uuid,
|
|
index = indicesByUUID[ uuid ];
|
|
|
|
if ( index !== undefined && index >= nCachedObjects ) {
|
|
|
|
// move existing object into the CACHED region
|
|
|
|
var lastCachedIndex = nCachedObjects ++,
|
|
firstActiveObject = objects[ lastCachedIndex ];
|
|
|
|
indicesByUUID[ firstActiveObject.uuid ] = index;
|
|
objects[ index ] = firstActiveObject;
|
|
|
|
indicesByUUID[ uuid ] = lastCachedIndex;
|
|
objects[ lastCachedIndex ] = object;
|
|
|
|
// accounting is done, now do the same for all bindings
|
|
|
|
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
|
|
|
|
var bindingsForPath = bindings[ j ],
|
|
firstActive = bindingsForPath[ lastCachedIndex ],
|
|
binding = bindingsForPath[ index ];
|
|
|
|
bindingsForPath[ index ] = firstActive;
|
|
bindingsForPath[ lastCachedIndex ] = binding;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // for arguments
|
|
|
|
this.nCachedObjects_ = nCachedObjects;
|
|
|
|
},
|
|
|
|
// remove & forget
|
|
uncache: function( var_args ) {
|
|
|
|
var objects = this._objects,
|
|
nObjects = objects.length,
|
|
nCachedObjects = this.nCachedObjects_,
|
|
indicesByUUID = this._indicesByUUID,
|
|
bindings = this._bindings,
|
|
nBindings = bindings.length;
|
|
|
|
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
|
|
|
|
var object = arguments[ i ],
|
|
uuid = object.uuid,
|
|
index = indicesByUUID[ uuid ];
|
|
|
|
if ( index !== undefined ) {
|
|
|
|
delete indicesByUUID[ uuid ];
|
|
|
|
if ( index < nCachedObjects ) {
|
|
|
|
// object is cached, shrink the CACHED region
|
|
|
|
var firstActiveIndex = -- nCachedObjects,
|
|
lastCachedObject = objects[ firstActiveIndex ],
|
|
lastIndex = -- nObjects,
|
|
lastObject = objects[ lastIndex ];
|
|
|
|
// last cached object takes this object's place
|
|
indicesByUUID[ lastCachedObject.uuid ] = index;
|
|
objects[ index ] = lastCachedObject;
|
|
|
|
// last object goes to the activated slot and pop
|
|
indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
|
|
objects[ firstActiveIndex ] = lastObject;
|
|
objects.pop();
|
|
|
|
// accounting is done, now do the same for all bindings
|
|
|
|
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
|
|
|
|
var bindingsForPath = bindings[ j ],
|
|
lastCached = bindingsForPath[ firstActiveIndex ],
|
|
last = bindingsForPath[ lastIndex ];
|
|
|
|
bindingsForPath[ index ] = lastCached;
|
|
bindingsForPath[ firstActiveIndex ] = last;
|
|
bindingsForPath.pop();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// object is active, just swap with the last and pop
|
|
|
|
var lastIndex = -- nObjects,
|
|
lastObject = objects[ lastIndex ];
|
|
|
|
indicesByUUID[ lastObject.uuid ] = index;
|
|
objects[ index ] = lastObject;
|
|
objects.pop();
|
|
|
|
// accounting is done, now do the same for all bindings
|
|
|
|
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
|
|
|
|
var bindingsForPath = bindings[ j ];
|
|
|
|
bindingsForPath[ index ] = bindingsForPath[ lastIndex ];
|
|
bindingsForPath.pop();
|
|
|
|
}
|
|
|
|
} // cached or active
|
|
|
|
} // if object is known
|
|
|
|
} // for arguments
|
|
|
|
this.nCachedObjects_ = nCachedObjects;
|
|
|
|
},
|
|
|
|
// Internal interface used by befriended PropertyBinding.Composite:
|
|
|
|
subscribe_: function ( path, parsedPath ) {
|
|
|
|
// returns an array of bindings for the given path that is changed
|
|
// according to the contained objects in the group
|
|
|
|
var indicesByPath = this._bindingsIndicesByPath,
|
|
index = indicesByPath[ path ],
|
|
bindings = this._bindings;
|
|
|
|
if ( index !== undefined ) return bindings[ index ];
|
|
|
|
var paths = this._paths,
|
|
parsedPaths = this._parsedPaths,
|
|
objects = this._objects,
|
|
nObjects = objects.length,
|
|
nCachedObjects = this.nCachedObjects_,
|
|
bindingsForPath = new Array( nObjects );
|
|
|
|
index = bindings.length;
|
|
|
|
indicesByPath[ path ] = index;
|
|
|
|
paths.push( path );
|
|
parsedPaths.push( parsedPath );
|
|
bindings.push( bindingsForPath );
|
|
|
|
for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
|
|
|
|
var object = objects[ i ];
|
|
bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
|
|
|
|
}
|
|
|
|
return bindingsForPath;
|
|
|
|
},
|
|
|
|
unsubscribe_: function ( path ) {
|
|
|
|
// tells the group to forget about a property path and no longer
|
|
// update the array previously obtained with 'subscribe_'
|
|
|
|
var indicesByPath = this._bindingsIndicesByPath,
|
|
index = indicesByPath[ path ];
|
|
|
|
if ( index !== undefined ) {
|
|
|
|
var paths = this._paths,
|
|
parsedPaths = this._parsedPaths,
|
|
bindings = this._bindings,
|
|
lastBindingsIndex = bindings.length - 1,
|
|
lastBindings = bindings[ lastBindingsIndex ],
|
|
lastBindingsPath = path[ lastBindingsIndex ];
|
|
|
|
indicesByPath[ lastBindingsPath ] = index;
|
|
|
|
bindings[ index ] = lastBindings;
|
|
bindings.pop();
|
|
|
|
parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
|
|
parsedPaths.pop();
|
|
|
|
paths[ index ] = paths[ lastBindingsIndex ];
|
|
paths.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* Action provided by AnimationMixer for scheduling clip playback on specific
|
|
* objects.
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*
|
|
*/
|
|
|
|
function AnimationAction( mixer, clip, localRoot ) {
|
|
|
|
this._mixer = mixer;
|
|
this._clip = clip;
|
|
this._localRoot = localRoot || null;
|
|
|
|
var tracks = clip.tracks,
|
|
nTracks = tracks.length,
|
|
interpolants = new Array( nTracks );
|
|
|
|
var interpolantSettings = {
|
|
endingStart: ZeroCurvatureEnding,
|
|
endingEnd: ZeroCurvatureEnding
|
|
};
|
|
|
|
for ( var i = 0; i !== nTracks; ++ i ) {
|
|
|
|
var interpolant = tracks[ i ].createInterpolant( null );
|
|
interpolants[ i ] = interpolant;
|
|
interpolant.settings = interpolantSettings;
|
|
|
|
}
|
|
|
|
this._interpolantSettings = interpolantSettings;
|
|
|
|
this._interpolants = interpolants; // bound by the mixer
|
|
|
|
// inside: PropertyMixer (managed by the mixer)
|
|
this._propertyBindings = new Array( nTracks );
|
|
|
|
this._cacheIndex = null; // for the memory manager
|
|
this._byClipCacheIndex = null; // for the memory manager
|
|
|
|
this._timeScaleInterpolant = null;
|
|
this._weightInterpolant = null;
|
|
|
|
this.loop = LoopRepeat;
|
|
this._loopCount = -1;
|
|
|
|
// global mixer time when the action is to be started
|
|
// it's set back to 'null' upon start of the action
|
|
this._startTime = null;
|
|
|
|
// scaled local time of the action
|
|
// gets clamped or wrapped to 0..clip.duration according to loop
|
|
this.time = 0;
|
|
|
|
this.timeScale = 1;
|
|
this._effectiveTimeScale = 1;
|
|
|
|
this.weight = 1;
|
|
this._effectiveWeight = 1;
|
|
|
|
this.repetitions = Infinity; // no. of repetitions when looping
|
|
|
|
this.paused = false; // true -> zero effective time scale
|
|
this.enabled = true; // false -> zero effective weight
|
|
|
|
this.clampWhenFinished = false; // keep feeding the last frame?
|
|
|
|
this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate
|
|
this.zeroSlopeAtEnd = true; // clips for start, loop and end
|
|
|
|
}
|
|
|
|
Object.assign( AnimationAction.prototype, {
|
|
|
|
// State & Scheduling
|
|
|
|
play: function() {
|
|
|
|
this._mixer._activateAction( this );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
stop: function() {
|
|
|
|
this._mixer._deactivateAction( this );
|
|
|
|
return this.reset();
|
|
|
|
},
|
|
|
|
reset: function() {
|
|
|
|
this.paused = false;
|
|
this.enabled = true;
|
|
|
|
this.time = 0; // restart clip
|
|
this._loopCount = -1; // forget previous loops
|
|
this._startTime = null; // forget scheduling
|
|
|
|
return this.stopFading().stopWarping();
|
|
|
|
},
|
|
|
|
isRunning: function() {
|
|
|
|
return this.enabled && ! this.paused && this.timeScale !== 0 &&
|
|
this._startTime === null && this._mixer._isActiveAction( this );
|
|
|
|
},
|
|
|
|
// return true when play has been called
|
|
isScheduled: function() {
|
|
|
|
return this._mixer._isActiveAction( this );
|
|
|
|
},
|
|
|
|
startAt: function( time ) {
|
|
|
|
this._startTime = time;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setLoop: function( mode, repetitions ) {
|
|
|
|
this.loop = mode;
|
|
this.repetitions = repetitions;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// Weight
|
|
|
|
// set the weight stopping any scheduled fading
|
|
// although .enabled = false yields an effective weight of zero, this
|
|
// method does *not* change .enabled, because it would be confusing
|
|
setEffectiveWeight: function( weight ) {
|
|
|
|
this.weight = weight;
|
|
|
|
// note: same logic as when updated at runtime
|
|
this._effectiveWeight = this.enabled ? weight : 0;
|
|
|
|
return this.stopFading();
|
|
|
|
},
|
|
|
|
// return the weight considering fading and .enabled
|
|
getEffectiveWeight: function() {
|
|
|
|
return this._effectiveWeight;
|
|
|
|
},
|
|
|
|
fadeIn: function( duration ) {
|
|
|
|
return this._scheduleFading( duration, 0, 1 );
|
|
|
|
},
|
|
|
|
fadeOut: function( duration ) {
|
|
|
|
return this._scheduleFading( duration, 1, 0 );
|
|
|
|
},
|
|
|
|
crossFadeFrom: function( fadeOutAction, duration, warp ) {
|
|
|
|
fadeOutAction.fadeOut( duration );
|
|
this.fadeIn( duration );
|
|
|
|
if( warp ) {
|
|
|
|
var fadeInDuration = this._clip.duration,
|
|
fadeOutDuration = fadeOutAction._clip.duration,
|
|
|
|
startEndRatio = fadeOutDuration / fadeInDuration,
|
|
endStartRatio = fadeInDuration / fadeOutDuration;
|
|
|
|
fadeOutAction.warp( 1.0, startEndRatio, duration );
|
|
this.warp( endStartRatio, 1.0, duration );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
crossFadeTo: function( fadeInAction, duration, warp ) {
|
|
|
|
return fadeInAction.crossFadeFrom( this, duration, warp );
|
|
|
|
},
|
|
|
|
stopFading: function() {
|
|
|
|
var weightInterpolant = this._weightInterpolant;
|
|
|
|
if ( weightInterpolant !== null ) {
|
|
|
|
this._weightInterpolant = null;
|
|
this._mixer._takeBackControlInterpolant( weightInterpolant );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// Time Scale Control
|
|
|
|
// set the time scale stopping any scheduled warping
|
|
// although .paused = true yields an effective time scale of zero, this
|
|
// method does *not* change .paused, because it would be confusing
|
|
setEffectiveTimeScale: function( timeScale ) {
|
|
|
|
this.timeScale = timeScale;
|
|
this._effectiveTimeScale = this.paused ? 0 :timeScale;
|
|
|
|
return this.stopWarping();
|
|
|
|
},
|
|
|
|
// return the time scale considering warping and .paused
|
|
getEffectiveTimeScale: function() {
|
|
|
|
return this._effectiveTimeScale;
|
|
|
|
},
|
|
|
|
setDuration: function( duration ) {
|
|
|
|
this.timeScale = this._clip.duration / duration;
|
|
|
|
return this.stopWarping();
|
|
|
|
},
|
|
|
|
syncWith: function( action ) {
|
|
|
|
this.time = action.time;
|
|
this.timeScale = action.timeScale;
|
|
|
|
return this.stopWarping();
|
|
|
|
},
|
|
|
|
halt: function( duration ) {
|
|
|
|
return this.warp( this._effectiveTimeScale, 0, duration );
|
|
|
|
},
|
|
|
|
warp: function( startTimeScale, endTimeScale, duration ) {
|
|
|
|
var mixer = this._mixer, now = mixer.time,
|
|
interpolant = this._timeScaleInterpolant,
|
|
|
|
timeScale = this.timeScale;
|
|
|
|
if ( interpolant === null ) {
|
|
|
|
interpolant = mixer._lendControlInterpolant();
|
|
this._timeScaleInterpolant = interpolant;
|
|
|
|
}
|
|
|
|
var times = interpolant.parameterPositions,
|
|
values = interpolant.sampleValues;
|
|
|
|
times[ 0 ] = now;
|
|
times[ 1 ] = now + duration;
|
|
|
|
values[ 0 ] = startTimeScale / timeScale;
|
|
values[ 1 ] = endTimeScale / timeScale;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
stopWarping: function() {
|
|
|
|
var timeScaleInterpolant = this._timeScaleInterpolant;
|
|
|
|
if ( timeScaleInterpolant !== null ) {
|
|
|
|
this._timeScaleInterpolant = null;
|
|
this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// Object Accessors
|
|
|
|
getMixer: function() {
|
|
|
|
return this._mixer;
|
|
|
|
},
|
|
|
|
getClip: function() {
|
|
|
|
return this._clip;
|
|
|
|
},
|
|
|
|
getRoot: function() {
|
|
|
|
return this._localRoot || this._mixer._root;
|
|
|
|
},
|
|
|
|
// Interna
|
|
|
|
_update: function( time, deltaTime, timeDirection, accuIndex ) {
|
|
|
|
// called by the mixer
|
|
|
|
if ( ! this.enabled ) {
|
|
|
|
// call ._updateWeight() to update ._effectiveWeight
|
|
|
|
this._updateWeight( time );
|
|
return;
|
|
|
|
}
|
|
|
|
var startTime = this._startTime;
|
|
|
|
if ( startTime !== null ) {
|
|
|
|
// check for scheduled start of action
|
|
|
|
var timeRunning = ( time - startTime ) * timeDirection;
|
|
if ( timeRunning < 0 || timeDirection === 0 ) {
|
|
|
|
return; // yet to come / don't decide when delta = 0
|
|
|
|
}
|
|
|
|
// start
|
|
|
|
this._startTime = null; // unschedule
|
|
deltaTime = timeDirection * timeRunning;
|
|
|
|
}
|
|
|
|
// apply time scale and advance time
|
|
|
|
deltaTime *= this._updateTimeScale( time );
|
|
var clipTime = this._updateTime( deltaTime );
|
|
|
|
// note: _updateTime may disable the action resulting in
|
|
// an effective weight of 0
|
|
|
|
var weight = this._updateWeight( time );
|
|
|
|
if ( weight > 0 ) {
|
|
|
|
var interpolants = this._interpolants;
|
|
var propertyMixers = this._propertyBindings;
|
|
|
|
for ( var j = 0, m = interpolants.length; j !== m; ++ j ) {
|
|
|
|
interpolants[ j ].evaluate( clipTime );
|
|
propertyMixers[ j ].accumulate( accuIndex, weight );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_updateWeight: function( time ) {
|
|
|
|
var weight = 0;
|
|
|
|
if ( this.enabled ) {
|
|
|
|
weight = this.weight;
|
|
var interpolant = this._weightInterpolant;
|
|
|
|
if ( interpolant !== null ) {
|
|
|
|
var interpolantValue = interpolant.evaluate( time )[ 0 ];
|
|
|
|
weight *= interpolantValue;
|
|
|
|
if ( time > interpolant.parameterPositions[ 1 ] ) {
|
|
|
|
this.stopFading();
|
|
|
|
if ( interpolantValue === 0 ) {
|
|
|
|
// faded out, disable
|
|
this.enabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this._effectiveWeight = weight;
|
|
return weight;
|
|
|
|
},
|
|
|
|
_updateTimeScale: function( time ) {
|
|
|
|
var timeScale = 0;
|
|
|
|
if ( ! this.paused ) {
|
|
|
|
timeScale = this.timeScale;
|
|
|
|
var interpolant = this._timeScaleInterpolant;
|
|
|
|
if ( interpolant !== null ) {
|
|
|
|
var interpolantValue = interpolant.evaluate( time )[ 0 ];
|
|
|
|
timeScale *= interpolantValue;
|
|
|
|
if ( time > interpolant.parameterPositions[ 1 ] ) {
|
|
|
|
this.stopWarping();
|
|
|
|
if ( timeScale === 0 ) {
|
|
|
|
// motion has halted, pause
|
|
this.paused = true;
|
|
|
|
} else {
|
|
|
|
// warp done - apply final time scale
|
|
this.timeScale = timeScale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this._effectiveTimeScale = timeScale;
|
|
return timeScale;
|
|
|
|
},
|
|
|
|
_updateTime: function( deltaTime ) {
|
|
|
|
var time = this.time + deltaTime;
|
|
|
|
if ( deltaTime === 0 ) return time;
|
|
|
|
var duration = this._clip.duration,
|
|
|
|
loop = this.loop,
|
|
loopCount = this._loopCount;
|
|
|
|
if ( loop === LoopOnce ) {
|
|
|
|
if ( loopCount === -1 ) {
|
|
// just started
|
|
|
|
this._loopCount = 0;
|
|
this._setEndings( true, true, false );
|
|
|
|
}
|
|
|
|
handle_stop: {
|
|
|
|
if ( time >= duration ) {
|
|
|
|
time = duration;
|
|
|
|
} else if ( time < 0 ) {
|
|
|
|
time = 0;
|
|
|
|
} else break handle_stop;
|
|
|
|
if ( this.clampWhenFinished ) this.paused = true;
|
|
else this.enabled = false;
|
|
|
|
this._mixer.dispatchEvent( {
|
|
type: 'finished', action: this,
|
|
direction: deltaTime < 0 ? -1 : 1
|
|
} );
|
|
|
|
}
|
|
|
|
} else { // repetitive Repeat or PingPong
|
|
|
|
var pingPong = ( loop === LoopPingPong );
|
|
|
|
if ( loopCount === -1 ) {
|
|
// just started
|
|
|
|
if ( deltaTime >= 0 ) {
|
|
|
|
loopCount = 0;
|
|
|
|
this._setEndings(
|
|
true, this.repetitions === 0, pingPong );
|
|
|
|
} else {
|
|
|
|
// when looping in reverse direction, the initial
|
|
// transition through zero counts as a repetition,
|
|
// so leave loopCount at -1
|
|
|
|
this._setEndings(
|
|
this.repetitions === 0, true, pingPong );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( time >= duration || time < 0 ) {
|
|
// wrap around
|
|
|
|
var loopDelta = Math.floor( time / duration ); // signed
|
|
time -= duration * loopDelta;
|
|
|
|
loopCount += Math.abs( loopDelta );
|
|
|
|
var pending = this.repetitions - loopCount;
|
|
|
|
if ( pending < 0 ) {
|
|
// have to stop (switch state, clamp time, fire event)
|
|
|
|
if ( this.clampWhenFinished ) this.paused = true;
|
|
else this.enabled = false;
|
|
|
|
time = deltaTime > 0 ? duration : 0;
|
|
|
|
this._mixer.dispatchEvent( {
|
|
type: 'finished', action: this,
|
|
direction: deltaTime > 0 ? 1 : -1
|
|
} );
|
|
|
|
} else {
|
|
// keep running
|
|
|
|
if ( pending === 0 ) {
|
|
// entering the last round
|
|
|
|
var atStart = deltaTime < 0;
|
|
this._setEndings( atStart, ! atStart, pingPong );
|
|
|
|
} else {
|
|
|
|
this._setEndings( false, false, pingPong );
|
|
|
|
}
|
|
|
|
this._loopCount = loopCount;
|
|
|
|
this._mixer.dispatchEvent( {
|
|
type: 'loop', action: this, loopDelta: loopDelta
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( pingPong && ( loopCount & 1 ) === 1 ) {
|
|
// invert time for the "pong round"
|
|
|
|
this.time = time;
|
|
return duration - time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.time = time;
|
|
return time;
|
|
|
|
},
|
|
|
|
_setEndings: function( atStart, atEnd, pingPong ) {
|
|
|
|
var settings = this._interpolantSettings;
|
|
|
|
if ( pingPong ) {
|
|
|
|
settings.endingStart = ZeroSlopeEnding;
|
|
settings.endingEnd = ZeroSlopeEnding;
|
|
|
|
} else {
|
|
|
|
// assuming for LoopOnce atStart == atEnd == true
|
|
|
|
if ( atStart ) {
|
|
|
|
settings.endingStart = this.zeroSlopeAtStart ?
|
|
ZeroSlopeEnding : ZeroCurvatureEnding;
|
|
|
|
} else {
|
|
|
|
settings.endingStart = WrapAroundEnding;
|
|
|
|
}
|
|
|
|
if ( atEnd ) {
|
|
|
|
settings.endingEnd = this.zeroSlopeAtEnd ?
|
|
ZeroSlopeEnding : ZeroCurvatureEnding;
|
|
|
|
} else {
|
|
|
|
settings.endingEnd = WrapAroundEnding;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_scheduleFading: function( duration, weightNow, weightThen ) {
|
|
|
|
var mixer = this._mixer, now = mixer.time,
|
|
interpolant = this._weightInterpolant;
|
|
|
|
if ( interpolant === null ) {
|
|
|
|
interpolant = mixer._lendControlInterpolant();
|
|
this._weightInterpolant = interpolant;
|
|
|
|
}
|
|
|
|
var times = interpolant.parameterPositions,
|
|
values = interpolant.sampleValues;
|
|
|
|
times[ 0 ] = now; values[ 0 ] = weightNow;
|
|
times[ 1 ] = now + duration; values[ 1 ] = weightThen;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
*
|
|
* Player for AnimationClips.
|
|
*
|
|
*
|
|
* @author Ben Houston / http://clara.io/
|
|
* @author David Sarno / http://lighthaus.us/
|
|
* @author tschw
|
|
*/
|
|
|
|
function AnimationMixer( root ) {
|
|
|
|
this._root = root;
|
|
this._initMemoryManager();
|
|
this._accuIndex = 0;
|
|
|
|
this.time = 0;
|
|
|
|
this.timeScale = 1.0;
|
|
|
|
}
|
|
|
|
Object.assign( AnimationMixer.prototype, EventDispatcher.prototype, {
|
|
|
|
_bindAction: function ( action, prototypeAction ) {
|
|
|
|
var root = action._localRoot || this._root,
|
|
tracks = action._clip.tracks,
|
|
nTracks = tracks.length,
|
|
bindings = action._propertyBindings,
|
|
interpolants = action._interpolants,
|
|
rootUuid = root.uuid,
|
|
bindingsByRoot = this._bindingsByRootAndName,
|
|
bindingsByName = bindingsByRoot[ rootUuid ];
|
|
|
|
if ( bindingsByName === undefined ) {
|
|
|
|
bindingsByName = {};
|
|
bindingsByRoot[ rootUuid ] = bindingsByName;
|
|
|
|
}
|
|
|
|
for ( var i = 0; i !== nTracks; ++ i ) {
|
|
|
|
var track = tracks[ i ],
|
|
trackName = track.name,
|
|
binding = bindingsByName[ trackName ];
|
|
|
|
if ( binding !== undefined ) {
|
|
|
|
bindings[ i ] = binding;
|
|
|
|
} else {
|
|
|
|
binding = bindings[ i ];
|
|
|
|
if ( binding !== undefined ) {
|
|
|
|
// existing binding, make sure the cache knows
|
|
|
|
if ( binding._cacheIndex === null ) {
|
|
|
|
++ binding.referenceCount;
|
|
this._addInactiveBinding( binding, rootUuid, trackName );
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
var path = prototypeAction && prototypeAction.
|
|
_propertyBindings[ i ].binding.parsedPath;
|
|
|
|
binding = new PropertyMixer(
|
|
PropertyBinding.create( root, trackName, path ),
|
|
track.ValueTypeName, track.getValueSize() );
|
|
|
|
++ binding.referenceCount;
|
|
this._addInactiveBinding( binding, rootUuid, trackName );
|
|
|
|
bindings[ i ] = binding;
|
|
|
|
}
|
|
|
|
interpolants[ i ].resultBuffer = binding.buffer;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_activateAction: function ( action ) {
|
|
|
|
if ( ! this._isActiveAction( action ) ) {
|
|
|
|
if ( action._cacheIndex === null ) {
|
|
|
|
// this action has been forgotten by the cache, but the user
|
|
// appears to be still using it -> rebind
|
|
|
|
var rootUuid = ( action._localRoot || this._root ).uuid,
|
|
clipUuid = action._clip.uuid,
|
|
actionsForClip = this._actionsByClip[ clipUuid ];
|
|
|
|
this._bindAction( action,
|
|
actionsForClip && actionsForClip.knownActions[ 0 ] );
|
|
|
|
this._addInactiveAction( action, clipUuid, rootUuid );
|
|
|
|
}
|
|
|
|
var bindings = action._propertyBindings;
|
|
|
|
// increment reference counts / sort out state
|
|
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
|
|
|
|
var binding = bindings[ i ];
|
|
|
|
if ( binding.useCount ++ === 0 ) {
|
|
|
|
this._lendBinding( binding );
|
|
binding.saveOriginalState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this._lendAction( action );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_deactivateAction: function ( action ) {
|
|
|
|
if ( this._isActiveAction( action ) ) {
|
|
|
|
var bindings = action._propertyBindings;
|
|
|
|
// decrement reference counts / sort out state
|
|
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
|
|
|
|
var binding = bindings[ i ];
|
|
|
|
if ( -- binding.useCount === 0 ) {
|
|
|
|
binding.restoreOriginalState();
|
|
this._takeBackBinding( binding );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this._takeBackAction( action );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Memory manager
|
|
|
|
_initMemoryManager: function () {
|
|
|
|
this._actions = []; // 'nActiveActions' followed by inactive ones
|
|
this._nActiveActions = 0;
|
|
|
|
this._actionsByClip = {};
|
|
// inside:
|
|
// {
|
|
// knownActions: Array< AnimationAction > - used as prototypes
|
|
// actionByRoot: AnimationAction - lookup
|
|
// }
|
|
|
|
|
|
this._bindings = []; // 'nActiveBindings' followed by inactive ones
|
|
this._nActiveBindings = 0;
|
|
|
|
this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
|
|
|
|
|
|
this._controlInterpolants = []; // same game as above
|
|
this._nActiveControlInterpolants = 0;
|
|
|
|
var scope = this;
|
|
|
|
this.stats = {
|
|
|
|
actions: {
|
|
get total() { return scope._actions.length; },
|
|
get inUse() { return scope._nActiveActions; }
|
|
},
|
|
bindings: {
|
|
get total() { return scope._bindings.length; },
|
|
get inUse() { return scope._nActiveBindings; }
|
|
},
|
|
controlInterpolants: {
|
|
get total() { return scope._controlInterpolants.length; },
|
|
get inUse() { return scope._nActiveControlInterpolants; }
|
|
}
|
|
|
|
};
|
|
|
|
},
|
|
|
|
// Memory management for AnimationAction objects
|
|
|
|
_isActiveAction: function ( action ) {
|
|
|
|
var index = action._cacheIndex;
|
|
return index !== null && index < this._nActiveActions;
|
|
|
|
},
|
|
|
|
_addInactiveAction: function ( action, clipUuid, rootUuid ) {
|
|
|
|
var actions = this._actions,
|
|
actionsByClip = this._actionsByClip,
|
|
actionsForClip = actionsByClip[ clipUuid ];
|
|
|
|
if ( actionsForClip === undefined ) {
|
|
|
|
actionsForClip = {
|
|
|
|
knownActions: [ action ],
|
|
actionByRoot: {}
|
|
|
|
};
|
|
|
|
action._byClipCacheIndex = 0;
|
|
|
|
actionsByClip[ clipUuid ] = actionsForClip;
|
|
|
|
} else {
|
|
|
|
var knownActions = actionsForClip.knownActions;
|
|
|
|
action._byClipCacheIndex = knownActions.length;
|
|
knownActions.push( action );
|
|
|
|
}
|
|
|
|
action._cacheIndex = actions.length;
|
|
actions.push( action );
|
|
|
|
actionsForClip.actionByRoot[ rootUuid ] = action;
|
|
|
|
},
|
|
|
|
_removeInactiveAction: function ( action ) {
|
|
|
|
var actions = this._actions,
|
|
lastInactiveAction = actions[ actions.length - 1 ],
|
|
cacheIndex = action._cacheIndex;
|
|
|
|
lastInactiveAction._cacheIndex = cacheIndex;
|
|
actions[ cacheIndex ] = lastInactiveAction;
|
|
actions.pop();
|
|
|
|
action._cacheIndex = null;
|
|
|
|
|
|
var clipUuid = action._clip.uuid,
|
|
actionsByClip = this._actionsByClip,
|
|
actionsForClip = actionsByClip[ clipUuid ],
|
|
knownActionsForClip = actionsForClip.knownActions,
|
|
|
|
lastKnownAction =
|
|
knownActionsForClip[ knownActionsForClip.length - 1 ],
|
|
|
|
byClipCacheIndex = action._byClipCacheIndex;
|
|
|
|
lastKnownAction._byClipCacheIndex = byClipCacheIndex;
|
|
knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
|
|
knownActionsForClip.pop();
|
|
|
|
action._byClipCacheIndex = null;
|
|
|
|
|
|
var actionByRoot = actionsForClip.actionByRoot,
|
|
rootUuid = ( action._localRoot || this._root ).uuid;
|
|
|
|
delete actionByRoot[ rootUuid ];
|
|
|
|
if ( knownActionsForClip.length === 0 ) {
|
|
|
|
delete actionsByClip[ clipUuid ];
|
|
|
|
}
|
|
|
|
this._removeInactiveBindingsForAction( action );
|
|
|
|
},
|
|
|
|
_removeInactiveBindingsForAction: function ( action ) {
|
|
|
|
var bindings = action._propertyBindings;
|
|
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
|
|
|
|
var binding = bindings[ i ];
|
|
|
|
if ( -- binding.referenceCount === 0 ) {
|
|
|
|
this._removeInactiveBinding( binding );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_lendAction: function ( action ) {
|
|
|
|
// [ active actions | inactive actions ]
|
|
// [ active actions >| inactive actions ]
|
|
// s a
|
|
// <-swap->
|
|
// a s
|
|
|
|
var actions = this._actions,
|
|
prevIndex = action._cacheIndex,
|
|
|
|
lastActiveIndex = this._nActiveActions ++,
|
|
|
|
firstInactiveAction = actions[ lastActiveIndex ];
|
|
|
|
action._cacheIndex = lastActiveIndex;
|
|
actions[ lastActiveIndex ] = action;
|
|
|
|
firstInactiveAction._cacheIndex = prevIndex;
|
|
actions[ prevIndex ] = firstInactiveAction;
|
|
|
|
},
|
|
|
|
_takeBackAction: function ( action ) {
|
|
|
|
// [ active actions | inactive actions ]
|
|
// [ active actions |< inactive actions ]
|
|
// a s
|
|
// <-swap->
|
|
// s a
|
|
|
|
var actions = this._actions,
|
|
prevIndex = action._cacheIndex,
|
|
|
|
firstInactiveIndex = -- this._nActiveActions,
|
|
|
|
lastActiveAction = actions[ firstInactiveIndex ];
|
|
|
|
action._cacheIndex = firstInactiveIndex;
|
|
actions[ firstInactiveIndex ] = action;
|
|
|
|
lastActiveAction._cacheIndex = prevIndex;
|
|
actions[ prevIndex ] = lastActiveAction;
|
|
|
|
},
|
|
|
|
// Memory management for PropertyMixer objects
|
|
|
|
_addInactiveBinding: function ( binding, rootUuid, trackName ) {
|
|
|
|
var bindingsByRoot = this._bindingsByRootAndName,
|
|
bindingByName = bindingsByRoot[ rootUuid ],
|
|
|
|
bindings = this._bindings;
|
|
|
|
if ( bindingByName === undefined ) {
|
|
|
|
bindingByName = {};
|
|
bindingsByRoot[ rootUuid ] = bindingByName;
|
|
|
|
}
|
|
|
|
bindingByName[ trackName ] = binding;
|
|
|
|
binding._cacheIndex = bindings.length;
|
|
bindings.push( binding );
|
|
|
|
},
|
|
|
|
_removeInactiveBinding: function ( binding ) {
|
|
|
|
var bindings = this._bindings,
|
|
propBinding = binding.binding,
|
|
rootUuid = propBinding.rootNode.uuid,
|
|
trackName = propBinding.path,
|
|
bindingsByRoot = this._bindingsByRootAndName,
|
|
bindingByName = bindingsByRoot[ rootUuid ],
|
|
|
|
lastInactiveBinding = bindings[ bindings.length - 1 ],
|
|
cacheIndex = binding._cacheIndex;
|
|
|
|
lastInactiveBinding._cacheIndex = cacheIndex;
|
|
bindings[ cacheIndex ] = lastInactiveBinding;
|
|
bindings.pop();
|
|
|
|
delete bindingByName[ trackName ];
|
|
|
|
remove_empty_map: {
|
|
|
|
for ( var _ in bindingByName ) break remove_empty_map;
|
|
|
|
delete bindingsByRoot[ rootUuid ];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_lendBinding: function ( binding ) {
|
|
|
|
var bindings = this._bindings,
|
|
prevIndex = binding._cacheIndex,
|
|
|
|
lastActiveIndex = this._nActiveBindings ++,
|
|
|
|
firstInactiveBinding = bindings[ lastActiveIndex ];
|
|
|
|
binding._cacheIndex = lastActiveIndex;
|
|
bindings[ lastActiveIndex ] = binding;
|
|
|
|
firstInactiveBinding._cacheIndex = prevIndex;
|
|
bindings[ prevIndex ] = firstInactiveBinding;
|
|
|
|
},
|
|
|
|
_takeBackBinding: function ( binding ) {
|
|
|
|
var bindings = this._bindings,
|
|
prevIndex = binding._cacheIndex,
|
|
|
|
firstInactiveIndex = -- this._nActiveBindings,
|
|
|
|
lastActiveBinding = bindings[ firstInactiveIndex ];
|
|
|
|
binding._cacheIndex = firstInactiveIndex;
|
|
bindings[ firstInactiveIndex ] = binding;
|
|
|
|
lastActiveBinding._cacheIndex = prevIndex;
|
|
bindings[ prevIndex ] = lastActiveBinding;
|
|
|
|
},
|
|
|
|
|
|
// Memory management of Interpolants for weight and time scale
|
|
|
|
_lendControlInterpolant: function () {
|
|
|
|
var interpolants = this._controlInterpolants,
|
|
lastActiveIndex = this._nActiveControlInterpolants ++,
|
|
interpolant = interpolants[ lastActiveIndex ];
|
|
|
|
if ( interpolant === undefined ) {
|
|
|
|
interpolant = new LinearInterpolant(
|
|
new Float32Array( 2 ), new Float32Array( 2 ),
|
|
1, this._controlInterpolantsResultBuffer );
|
|
|
|
interpolant.__cacheIndex = lastActiveIndex;
|
|
interpolants[ lastActiveIndex ] = interpolant;
|
|
|
|
}
|
|
|
|
return interpolant;
|
|
|
|
},
|
|
|
|
_takeBackControlInterpolant: function ( interpolant ) {
|
|
|
|
var interpolants = this._controlInterpolants,
|
|
prevIndex = interpolant.__cacheIndex,
|
|
|
|
firstInactiveIndex = -- this._nActiveControlInterpolants,
|
|
|
|
lastActiveInterpolant = interpolants[ firstInactiveIndex ];
|
|
|
|
interpolant.__cacheIndex = firstInactiveIndex;
|
|
interpolants[ firstInactiveIndex ] = interpolant;
|
|
|
|
lastActiveInterpolant.__cacheIndex = prevIndex;
|
|
interpolants[ prevIndex ] = lastActiveInterpolant;
|
|
|
|
},
|
|
|
|
_controlInterpolantsResultBuffer: new Float32Array( 1 ),
|
|
|
|
// return an action for a clip optionally using a custom root target
|
|
// object (this method allocates a lot of dynamic memory in case a
|
|
// previously unknown clip/root combination is specified)
|
|
clipAction: function ( clip, optionalRoot ) {
|
|
|
|
var root = optionalRoot || this._root,
|
|
rootUuid = root.uuid,
|
|
|
|
clipObject = typeof clip === 'string' ?
|
|
AnimationClip.findByName( root, clip ) : clip,
|
|
|
|
clipUuid = clipObject !== null ? clipObject.uuid : clip,
|
|
|
|
actionsForClip = this._actionsByClip[ clipUuid ],
|
|
prototypeAction = null;
|
|
|
|
if ( actionsForClip !== undefined ) {
|
|
|
|
var existingAction =
|
|
actionsForClip.actionByRoot[ rootUuid ];
|
|
|
|
if ( existingAction !== undefined ) {
|
|
|
|
return existingAction;
|
|
|
|
}
|
|
|
|
// we know the clip, so we don't have to parse all
|
|
// the bindings again but can just copy
|
|
prototypeAction = actionsForClip.knownActions[ 0 ];
|
|
|
|
// also, take the clip from the prototype action
|
|
if ( clipObject === null )
|
|
clipObject = prototypeAction._clip;
|
|
|
|
}
|
|
|
|
// clip must be known when specified via string
|
|
if ( clipObject === null ) return null;
|
|
|
|
// allocate all resources required to run it
|
|
var newAction = new AnimationAction( this, clipObject, optionalRoot );
|
|
|
|
this._bindAction( newAction, prototypeAction );
|
|
|
|
// and make the action known to the memory manager
|
|
this._addInactiveAction( newAction, clipUuid, rootUuid );
|
|
|
|
return newAction;
|
|
|
|
},
|
|
|
|
// get an existing action
|
|
existingAction: function ( clip, optionalRoot ) {
|
|
|
|
var root = optionalRoot || this._root,
|
|
rootUuid = root.uuid,
|
|
|
|
clipObject = typeof clip === 'string' ?
|
|
AnimationClip.findByName( root, clip ) : clip,
|
|
|
|
clipUuid = clipObject ? clipObject.uuid : clip,
|
|
|
|
actionsForClip = this._actionsByClip[ clipUuid ];
|
|
|
|
if ( actionsForClip !== undefined ) {
|
|
|
|
return actionsForClip.actionByRoot[ rootUuid ] || null;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
// deactivates all previously scheduled actions
|
|
stopAllAction: function () {
|
|
|
|
var actions = this._actions,
|
|
nActions = this._nActiveActions,
|
|
bindings = this._bindings,
|
|
nBindings = this._nActiveBindings;
|
|
|
|
this._nActiveActions = 0;
|
|
this._nActiveBindings = 0;
|
|
|
|
for ( var i = 0; i !== nActions; ++ i ) {
|
|
|
|
actions[ i ].reset();
|
|
|
|
}
|
|
|
|
for ( var i = 0; i !== nBindings; ++ i ) {
|
|
|
|
bindings[ i ].useCount = 0;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// advance the time and update apply the animation
|
|
update: function ( deltaTime ) {
|
|
|
|
deltaTime *= this.timeScale;
|
|
|
|
var actions = this._actions,
|
|
nActions = this._nActiveActions,
|
|
|
|
time = this.time += deltaTime,
|
|
timeDirection = Math.sign( deltaTime ),
|
|
|
|
accuIndex = this._accuIndex ^= 1;
|
|
|
|
// run active actions
|
|
|
|
for ( var i = 0; i !== nActions; ++ i ) {
|
|
|
|
var action = actions[ i ];
|
|
|
|
action._update( time, deltaTime, timeDirection, accuIndex );
|
|
|
|
}
|
|
|
|
// update scene graph
|
|
|
|
var bindings = this._bindings,
|
|
nBindings = this._nActiveBindings;
|
|
|
|
for ( var i = 0; i !== nBindings; ++ i ) {
|
|
|
|
bindings[ i ].apply( accuIndex );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// return this mixer's root target object
|
|
getRoot: function () {
|
|
|
|
return this._root;
|
|
|
|
},
|
|
|
|
// free all resources specific to a particular clip
|
|
uncacheClip: function ( clip ) {
|
|
|
|
var actions = this._actions,
|
|
clipUuid = clip.uuid,
|
|
actionsByClip = this._actionsByClip,
|
|
actionsForClip = actionsByClip[ clipUuid ];
|
|
|
|
if ( actionsForClip !== undefined ) {
|
|
|
|
// note: just calling _removeInactiveAction would mess up the
|
|
// iteration state and also require updating the state we can
|
|
// just throw away
|
|
|
|
var actionsToRemove = actionsForClip.knownActions;
|
|
|
|
for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
|
|
|
|
var action = actionsToRemove[ i ];
|
|
|
|
this._deactivateAction( action );
|
|
|
|
var cacheIndex = action._cacheIndex,
|
|
lastInactiveAction = actions[ actions.length - 1 ];
|
|
|
|
action._cacheIndex = null;
|
|
action._byClipCacheIndex = null;
|
|
|
|
lastInactiveAction._cacheIndex = cacheIndex;
|
|
actions[ cacheIndex ] = lastInactiveAction;
|
|
actions.pop();
|
|
|
|
this._removeInactiveBindingsForAction( action );
|
|
|
|
}
|
|
|
|
delete actionsByClip[ clipUuid ];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// free all resources specific to a particular root target object
|
|
uncacheRoot: function ( root ) {
|
|
|
|
var rootUuid = root.uuid,
|
|
actionsByClip = this._actionsByClip;
|
|
|
|
for ( var clipUuid in actionsByClip ) {
|
|
|
|
var actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
|
|
action = actionByRoot[ rootUuid ];
|
|
|
|
if ( action !== undefined ) {
|
|
|
|
this._deactivateAction( action );
|
|
this._removeInactiveAction( action );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var bindingsByRoot = this._bindingsByRootAndName,
|
|
bindingByName = bindingsByRoot[ rootUuid ];
|
|
|
|
if ( bindingByName !== undefined ) {
|
|
|
|
for ( var trackName in bindingByName ) {
|
|
|
|
var binding = bindingByName[ trackName ];
|
|
binding.restoreOriginalState();
|
|
this._removeInactiveBinding( binding );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// remove a targeted clip from the cache
|
|
uncacheAction: function ( clip, optionalRoot ) {
|
|
|
|
var action = this.existingAction( clip, optionalRoot );
|
|
|
|
if ( action !== null ) {
|
|
|
|
this._deactivateAction( action );
|
|
this._removeInactiveAction( action );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function Uniform( value ) {
|
|
|
|
if ( typeof value === 'string' ) {
|
|
|
|
console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
|
|
value = arguments[ 1 ];
|
|
|
|
}
|
|
|
|
this.value = value;
|
|
|
|
}
|
|
|
|
Uniform.prototype.clone = function () {
|
|
|
|
return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
|
|
|
|
};
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
*/
|
|
|
|
function InstancedBufferGeometry() {
|
|
|
|
BufferGeometry.call( this );
|
|
|
|
this.type = 'InstancedBufferGeometry';
|
|
this.maxInstancedCount = undefined;
|
|
|
|
}
|
|
|
|
InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
|
|
|
|
constructor: InstancedBufferGeometry,
|
|
|
|
isInstancedBufferGeometry: true,
|
|
|
|
addGroup: function ( start, count, materialIndex ) {
|
|
|
|
this.groups.push( {
|
|
|
|
start: start,
|
|
count: count,
|
|
materialIndex: materialIndex
|
|
|
|
} );
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
var index = source.index;
|
|
|
|
if ( index !== null ) {
|
|
|
|
this.setIndex( index.clone() );
|
|
|
|
}
|
|
|
|
var attributes = source.attributes;
|
|
|
|
for ( var name in attributes ) {
|
|
|
|
var attribute = attributes[ name ];
|
|
this.addAttribute( name, attribute.clone() );
|
|
|
|
}
|
|
|
|
var groups = source.groups;
|
|
|
|
for ( var i = 0, l = groups.length; i < l; i ++ ) {
|
|
|
|
var group = groups[ i ];
|
|
this.addGroup( group.start, group.count, group.materialIndex );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
*/
|
|
|
|
function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.data = interleavedBuffer;
|
|
this.itemSize = itemSize;
|
|
this.offset = offset;
|
|
|
|
this.normalized = normalized === true;
|
|
|
|
}
|
|
|
|
Object.defineProperties( InterleavedBufferAttribute.prototype, {
|
|
|
|
count: {
|
|
|
|
get: function () {
|
|
|
|
return this.data.count;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
array: {
|
|
|
|
get: function () {
|
|
|
|
return this.data.array;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( InterleavedBufferAttribute.prototype, {
|
|
|
|
isInterleavedBufferAttribute: true,
|
|
|
|
setX: function ( index, x ) {
|
|
|
|
this.data.array[ index * this.data.stride + this.offset ] = x;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setY: function ( index, y ) {
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setZ: function ( index, z ) {
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setW: function ( index, w ) {
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
getX: function ( index ) {
|
|
|
|
return this.data.array[ index * this.data.stride + this.offset ];
|
|
|
|
},
|
|
|
|
getY: function ( index ) {
|
|
|
|
return this.data.array[ index * this.data.stride + this.offset + 1 ];
|
|
|
|
},
|
|
|
|
getZ: function ( index ) {
|
|
|
|
return this.data.array[ index * this.data.stride + this.offset + 2 ];
|
|
|
|
},
|
|
|
|
getW: function ( index ) {
|
|
|
|
return this.data.array[ index * this.data.stride + this.offset + 3 ];
|
|
|
|
},
|
|
|
|
setXY: function ( index, x, y ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setXYZ: function ( index, x, y, z ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
this.data.array[ index + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setXYZW: function ( index, x, y, z, w ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
this.data.array[ index + 2 ] = z;
|
|
this.data.array[ index + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
*/
|
|
|
|
function InterleavedBuffer( array, stride ) {
|
|
|
|
this.uuid = _Math.generateUUID();
|
|
|
|
this.array = array;
|
|
this.stride = stride;
|
|
this.count = array !== undefined ? array.length / stride : 0;
|
|
|
|
this.dynamic = false;
|
|
this.updateRange = { offset: 0, count: - 1 };
|
|
|
|
this.onUploadCallback = function () {};
|
|
|
|
this.version = 0;
|
|
|
|
}
|
|
|
|
Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
|
|
|
|
set: function ( value ) {
|
|
|
|
if ( value === true ) this.version ++;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( InterleavedBuffer.prototype, {
|
|
|
|
isInterleavedBuffer: true,
|
|
|
|
setArray: function ( array ) {
|
|
|
|
if ( Array.isArray( array ) ) {
|
|
|
|
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
|
|
|
}
|
|
|
|
this.count = array !== undefined ? array.length / this.stride : 0;
|
|
this.array = array;
|
|
|
|
},
|
|
|
|
setDynamic: function ( value ) {
|
|
|
|
this.dynamic = value;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copy: function ( source ) {
|
|
|
|
this.array = new source.array.constructor( source.array );
|
|
this.count = source.count;
|
|
this.stride = source.stride;
|
|
this.dynamic = source.dynamic;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
copyAt: function ( index1, attribute, index2 ) {
|
|
|
|
index1 *= this.stride;
|
|
index2 *= attribute.stride;
|
|
|
|
for ( var i = 0, l = this.stride; i < l; i ++ ) {
|
|
|
|
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
set: function ( value, offset ) {
|
|
|
|
if ( offset === undefined ) offset = 0;
|
|
|
|
this.array.set( value, offset );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
onUpload: function ( callback ) {
|
|
|
|
this.onUploadCallback = callback;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
*/
|
|
|
|
function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
|
|
|
|
InterleavedBuffer.call( this, array, stride );
|
|
|
|
this.meshPerAttribute = meshPerAttribute || 1;
|
|
|
|
}
|
|
|
|
InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
|
|
|
|
constructor: InstancedInterleavedBuffer,
|
|
|
|
isInstancedInterleavedBuffer: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
InterleavedBuffer.prototype.copy.call( this, source );
|
|
|
|
this.meshPerAttribute = source.meshPerAttribute;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author benaadams / https://twitter.com/ben_a_adams
|
|
*/
|
|
|
|
function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {
|
|
|
|
BufferAttribute.call( this, array, itemSize );
|
|
|
|
this.meshPerAttribute = meshPerAttribute || 1;
|
|
|
|
}
|
|
|
|
InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
|
|
|
|
constructor: InstancedBufferAttribute,
|
|
|
|
isInstancedBufferAttribute: true,
|
|
|
|
copy: function ( source ) {
|
|
|
|
BufferAttribute.prototype.copy.call( this, source );
|
|
|
|
this.meshPerAttribute = source.meshPerAttribute;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author bhouston / http://clara.io/
|
|
* @author stephomi / http://stephaneginier.com/
|
|
*/
|
|
|
|
function Raycaster( origin, direction, near, far ) {
|
|
|
|
this.ray = new Ray( origin, direction );
|
|
// direction is assumed to be normalized (for accurate distance calculations)
|
|
|
|
this.near = near || 0;
|
|
this.far = far || Infinity;
|
|
|
|
this.params = {
|
|
Mesh: {},
|
|
Line: {},
|
|
LOD: {},
|
|
Points: { threshold: 1 },
|
|
Sprite: {}
|
|
};
|
|
|
|
Object.defineProperties( this.params, {
|
|
PointCloud: {
|
|
get: function () {
|
|
console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
|
|
return this.Points;
|
|
}
|
|
}
|
|
} );
|
|
|
|
}
|
|
|
|
function ascSort( a, b ) {
|
|
|
|
return a.distance - b.distance;
|
|
|
|
}
|
|
|
|
function intersectObject( object, raycaster, intersects, recursive ) {
|
|
|
|
if ( object.visible === false ) return;
|
|
|
|
object.raycast( raycaster, intersects );
|
|
|
|
if ( recursive === true ) {
|
|
|
|
var children = object.children;
|
|
|
|
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
|
|
|
intersectObject( children[ i ], raycaster, intersects, true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Object.assign( Raycaster.prototype, {
|
|
|
|
linePrecision: 1,
|
|
|
|
set: function ( origin, direction ) {
|
|
|
|
// direction is assumed to be normalized (for accurate distance calculations)
|
|
|
|
this.ray.set( origin, direction );
|
|
|
|
},
|
|
|
|
setFromCamera: function ( coords, camera ) {
|
|
|
|
if ( ( camera && camera.isPerspectiveCamera ) ) {
|
|
|
|
this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
|
|
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
|
|
|
|
} else if ( ( camera && camera.isOrthographicCamera ) ) {
|
|
|
|
this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
|
|
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
|
|
|
|
} else {
|
|
|
|
console.error( 'THREE.Raycaster: Unsupported camera type.' );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
intersectObject: function ( object, recursive ) {
|
|
|
|
var intersects = [];
|
|
|
|
intersectObject( object, this, intersects, recursive );
|
|
|
|
intersects.sort( ascSort );
|
|
|
|
return intersects;
|
|
|
|
},
|
|
|
|
intersectObjects: function ( objects, recursive ) {
|
|
|
|
var intersects = [];
|
|
|
|
if ( Array.isArray( objects ) === false ) {
|
|
|
|
console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
|
|
return intersects;
|
|
|
|
}
|
|
|
|
for ( var i = 0, l = objects.length; i < l; i ++ ) {
|
|
|
|
intersectObject( objects[ i ], this, intersects, recursive );
|
|
|
|
}
|
|
|
|
intersects.sort( ascSort );
|
|
|
|
return intersects;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function Clock( autoStart ) {
|
|
|
|
this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
|
|
|
|
this.startTime = 0;
|
|
this.oldTime = 0;
|
|
this.elapsedTime = 0;
|
|
|
|
this.running = false;
|
|
|
|
}
|
|
|
|
Object.assign( Clock.prototype, {
|
|
|
|
start: function () {
|
|
|
|
this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
|
|
|
|
this.oldTime = this.startTime;
|
|
this.elapsedTime = 0;
|
|
this.running = true;
|
|
|
|
},
|
|
|
|
stop: function () {
|
|
|
|
this.getElapsedTime();
|
|
this.running = false;
|
|
|
|
},
|
|
|
|
getElapsedTime: function () {
|
|
|
|
this.getDelta();
|
|
return this.elapsedTime;
|
|
|
|
},
|
|
|
|
getDelta: function () {
|
|
|
|
var diff = 0;
|
|
|
|
if ( this.autoStart && ! this.running ) {
|
|
|
|
this.start();
|
|
return 0;
|
|
|
|
}
|
|
|
|
if ( this.running ) {
|
|
|
|
var newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
|
|
|
|
diff = ( newTime - this.oldTime ) / 1000;
|
|
this.oldTime = newTime;
|
|
|
|
this.elapsedTime += diff;
|
|
|
|
}
|
|
|
|
return diff;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author bhouston / http://clara.io
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*
|
|
* Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
|
|
*
|
|
* The poles (phi) are at the positive and negative y axis.
|
|
* The equator starts at positive z.
|
|
*/
|
|
|
|
function Spherical( radius, phi, theta ) {
|
|
|
|
this.radius = ( radius !== undefined ) ? radius : 1.0;
|
|
this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole
|
|
this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
Object.assign( Spherical.prototype, {
|
|
|
|
set: function ( radius, phi, theta ) {
|
|
|
|
this.radius = radius;
|
|
this.phi = phi;
|
|
this.theta = theta;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( other ) {
|
|
|
|
this.radius = other.radius;
|
|
this.phi = other.phi;
|
|
this.theta = other.theta;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
// restrict phi to be betwee EPS and PI-EPS
|
|
makeSafe: function() {
|
|
|
|
var EPS = 0.000001;
|
|
this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromVector3: function( vec3 ) {
|
|
|
|
this.radius = vec3.length();
|
|
|
|
if ( this.radius === 0 ) {
|
|
|
|
this.theta = 0;
|
|
this.phi = 0;
|
|
|
|
} else {
|
|
|
|
this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis
|
|
this.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*
|
|
* Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
|
|
*
|
|
*/
|
|
|
|
function Cylindrical( radius, theta, y ) {
|
|
|
|
this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane
|
|
this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
|
|
this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
Object.assign( Cylindrical.prototype, {
|
|
|
|
set: function ( radius, theta, y ) {
|
|
|
|
this.radius = radius;
|
|
this.theta = theta;
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
clone: function () {
|
|
|
|
return new this.constructor().copy( this );
|
|
|
|
},
|
|
|
|
copy: function ( other ) {
|
|
|
|
this.radius = other.radius;
|
|
this.theta = other.theta;
|
|
this.y = other.y;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
setFromVector3: function( vec3 ) {
|
|
|
|
this.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );
|
|
this.theta = Math.atan2( vec3.x, vec3.z );
|
|
this.y = vec3.y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function MorphBlendMesh( geometry, material ) {
|
|
|
|
Mesh.call( this, geometry, material );
|
|
|
|
this.animationsMap = {};
|
|
this.animationsList = [];
|
|
|
|
// prepare default animation
|
|
// (all frames played together in 1 second)
|
|
|
|
var numFrames = this.geometry.morphTargets.length;
|
|
|
|
var name = "__default";
|
|
|
|
var startFrame = 0;
|
|
var endFrame = numFrames - 1;
|
|
|
|
var fps = numFrames / 1;
|
|
|
|
this.createAnimation( name, startFrame, endFrame, fps );
|
|
this.setAnimationWeight( name, 1 );
|
|
|
|
}
|
|
|
|
MorphBlendMesh.prototype = Object.create( Mesh.prototype );
|
|
MorphBlendMesh.prototype.constructor = MorphBlendMesh;
|
|
|
|
MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
|
|
|
|
var animation = {
|
|
|
|
start: start,
|
|
end: end,
|
|
|
|
length: end - start + 1,
|
|
|
|
fps: fps,
|
|
duration: ( end - start ) / fps,
|
|
|
|
lastFrame: 0,
|
|
currentFrame: 0,
|
|
|
|
active: false,
|
|
|
|
time: 0,
|
|
direction: 1,
|
|
weight: 1,
|
|
|
|
directionBackwards: false,
|
|
mirroredLoop: false
|
|
|
|
};
|
|
|
|
this.animationsMap[ name ] = animation;
|
|
this.animationsList.push( animation );
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
|
|
|
|
var pattern = /([a-z]+)_?(\d+)/i;
|
|
|
|
var firstAnimation, frameRanges = {};
|
|
|
|
var geometry = this.geometry;
|
|
|
|
for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
|
|
|
|
var morph = geometry.morphTargets[ i ];
|
|
var chunks = morph.name.match( pattern );
|
|
|
|
if ( chunks && chunks.length > 1 ) {
|
|
|
|
var name = chunks[ 1 ];
|
|
|
|
if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };
|
|
|
|
var range = frameRanges[ name ];
|
|
|
|
if ( i < range.start ) range.start = i;
|
|
if ( i > range.end ) range.end = i;
|
|
|
|
if ( ! firstAnimation ) firstAnimation = name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( var name in frameRanges ) {
|
|
|
|
var range = frameRanges[ name ];
|
|
this.createAnimation( name, range.start, range.end, fps );
|
|
|
|
}
|
|
|
|
this.firstAnimation = firstAnimation;
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.direction = 1;
|
|
animation.directionBackwards = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.direction = - 1;
|
|
animation.directionBackwards = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.fps = fps;
|
|
animation.duration = ( animation.end - animation.start ) / animation.fps;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.duration = duration;
|
|
animation.fps = ( animation.end - animation.start ) / animation.duration;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.weight = weight;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.time = time;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
|
|
|
|
var time = 0;
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
time = animation.time;
|
|
|
|
}
|
|
|
|
return time;
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
|
|
|
|
var duration = - 1;
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
duration = animation.duration;
|
|
|
|
}
|
|
|
|
return duration;
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.playAnimation = function ( name ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.time = 0;
|
|
animation.active = true;
|
|
|
|
} else {
|
|
|
|
console.warn( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.stopAnimation = function ( name ) {
|
|
|
|
var animation = this.animationsMap[ name ];
|
|
|
|
if ( animation ) {
|
|
|
|
animation.active = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
MorphBlendMesh.prototype.update = function ( delta ) {
|
|
|
|
for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
|
|
|
|
var animation = this.animationsList[ i ];
|
|
|
|
if ( ! animation.active ) continue;
|
|
|
|
var frameTime = animation.duration / animation.length;
|
|
|
|
animation.time += animation.direction * delta;
|
|
|
|
if ( animation.mirroredLoop ) {
|
|
|
|
if ( animation.time > animation.duration || animation.time < 0 ) {
|
|
|
|
animation.direction *= - 1;
|
|
|
|
if ( animation.time > animation.duration ) {
|
|
|
|
animation.time = animation.duration;
|
|
animation.directionBackwards = true;
|
|
|
|
}
|
|
|
|
if ( animation.time < 0 ) {
|
|
|
|
animation.time = 0;
|
|
animation.directionBackwards = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
animation.time = animation.time % animation.duration;
|
|
|
|
if ( animation.time < 0 ) animation.time += animation.duration;
|
|
|
|
}
|
|
|
|
var keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
|
|
var weight = animation.weight;
|
|
|
|
if ( keyframe !== animation.currentFrame ) {
|
|
|
|
this.morphTargetInfluences[ animation.lastFrame ] = 0;
|
|
this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
|
|
|
|
this.morphTargetInfluences[ keyframe ] = 0;
|
|
|
|
animation.lastFrame = animation.currentFrame;
|
|
animation.currentFrame = keyframe;
|
|
|
|
}
|
|
|
|
var mix = ( animation.time % frameTime ) / frameTime;
|
|
|
|
if ( animation.directionBackwards ) mix = 1 - mix;
|
|
|
|
if ( animation.currentFrame !== animation.lastFrame ) {
|
|
|
|
this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
|
|
this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
|
|
|
|
} else {
|
|
|
|
this.morphTargetInfluences[ animation.currentFrame ] = weight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
*/
|
|
|
|
function ImmediateRenderObject( material ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.material = material;
|
|
this.render = function ( renderCallback ) {};
|
|
|
|
}
|
|
|
|
ImmediateRenderObject.prototype = Object.create( Object3D.prototype );
|
|
ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
|
|
|
|
ImmediateRenderObject.prototype.isImmediateRenderObject = true;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function VertexNormalsHelper( object, size, hex, linewidth ) {
|
|
|
|
this.object = object;
|
|
|
|
this.size = ( size !== undefined ) ? size : 1;
|
|
|
|
var color = ( hex !== undefined ) ? hex : 0xff0000;
|
|
|
|
var width = ( linewidth !== undefined ) ? linewidth : 1;
|
|
|
|
//
|
|
|
|
var nNormals = 0;
|
|
|
|
var objGeometry = this.object.geometry;
|
|
|
|
if ( objGeometry && objGeometry.isGeometry ) {
|
|
|
|
nNormals = objGeometry.faces.length * 3;
|
|
|
|
} else if ( objGeometry && objGeometry.isBufferGeometry ) {
|
|
|
|
nNormals = objGeometry.attributes.normal.count;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
|
|
|
|
geometry.addAttribute( 'position', positions );
|
|
|
|
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );
|
|
|
|
//
|
|
|
|
this.matrixAutoUpdate = false;
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
VertexNormalsHelper.prototype = Object.create( LineSegments.prototype );
|
|
VertexNormalsHelper.prototype.constructor = VertexNormalsHelper;
|
|
|
|
VertexNormalsHelper.prototype.update = ( function () {
|
|
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
var normalMatrix = new Matrix3();
|
|
|
|
return function update() {
|
|
|
|
var keys = [ 'a', 'b', 'c' ];
|
|
|
|
this.object.updateMatrixWorld( true );
|
|
|
|
normalMatrix.getNormalMatrix( this.object.matrixWorld );
|
|
|
|
var matrixWorld = this.object.matrixWorld;
|
|
|
|
var position = this.geometry.attributes.position;
|
|
|
|
//
|
|
|
|
var objGeometry = this.object.geometry;
|
|
|
|
if ( objGeometry && objGeometry.isGeometry ) {
|
|
|
|
var vertices = objGeometry.vertices;
|
|
|
|
var faces = objGeometry.faces;
|
|
|
|
var idx = 0;
|
|
|
|
for ( var i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
|
|
|
|
var vertex = vertices[ face[ keys[ j ] ] ];
|
|
|
|
var normal = face.vertexNormals[ j ];
|
|
|
|
v1.copy( vertex ).applyMatrix4( matrixWorld );
|
|
|
|
v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
|
|
|
|
position.setXYZ( idx, v1.x, v1.y, v1.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
position.setXYZ( idx, v2.x, v2.y, v2.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( objGeometry && objGeometry.isBufferGeometry ) {
|
|
|
|
var objPos = objGeometry.attributes.position;
|
|
|
|
var objNorm = objGeometry.attributes.normal;
|
|
|
|
var idx = 0;
|
|
|
|
// for simplicity, ignore index and drawcalls, and render every normal
|
|
|
|
for ( var j = 0, jl = objPos.count; j < jl; j ++ ) {
|
|
|
|
v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );
|
|
|
|
v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );
|
|
|
|
v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
|
|
|
|
position.setXYZ( idx, v1.x, v1.y, v1.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
position.setXYZ( idx, v2.x, v2.y, v2.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
position.needsUpdate = true;
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function SpotLightHelper( light ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.light = light;
|
|
this.light.updateMatrixWorld();
|
|
|
|
this.matrix = light.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
var positions = [
|
|
0, 0, 0, 0, 0, 1,
|
|
0, 0, 0, 1, 0, 1,
|
|
0, 0, 0, - 1, 0, 1,
|
|
0, 0, 0, 0, 1, 1,
|
|
0, 0, 0, 0, - 1, 1
|
|
];
|
|
|
|
for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {
|
|
|
|
var p1 = ( i / l ) * Math.PI * 2;
|
|
var p2 = ( j / l ) * Math.PI * 2;
|
|
|
|
positions.push(
|
|
Math.cos( p1 ), Math.sin( p1 ), 1,
|
|
Math.cos( p2 ), Math.sin( p2 ), 1
|
|
);
|
|
|
|
}
|
|
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { fog: false } );
|
|
|
|
this.cone = new LineSegments( geometry, material );
|
|
this.add( this.cone );
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
SpotLightHelper.prototype = Object.create( Object3D.prototype );
|
|
SpotLightHelper.prototype.constructor = SpotLightHelper;
|
|
|
|
SpotLightHelper.prototype.dispose = function () {
|
|
|
|
this.cone.geometry.dispose();
|
|
this.cone.material.dispose();
|
|
|
|
};
|
|
|
|
SpotLightHelper.prototype.update = function () {
|
|
|
|
var vector = new Vector3();
|
|
var vector2 = new Vector3();
|
|
|
|
return function update() {
|
|
|
|
var coneLength = this.light.distance ? this.light.distance : 1000;
|
|
var coneWidth = coneLength * Math.tan( this.light.angle );
|
|
|
|
this.cone.scale.set( coneWidth, coneWidth, coneLength );
|
|
|
|
vector.setFromMatrixPosition( this.light.matrixWorld );
|
|
vector2.setFromMatrixPosition( this.light.target.matrixWorld );
|
|
|
|
this.cone.lookAt( vector2.sub( vector ) );
|
|
|
|
this.cone.material.color.copy( this.light.color );
|
|
|
|
};
|
|
|
|
}();
|
|
|
|
/**
|
|
* @author Sean Griffin / http://twitter.com/sgrif
|
|
* @author Michael Guerrero / http://realitymeltdown.com
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author ikerr / http://verold.com
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
function SkeletonHelper( object ) {
|
|
|
|
this.bones = this.getBoneList( object );
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
var vertices = [];
|
|
var colors = [];
|
|
|
|
var color1 = new Color( 0, 0, 1 );
|
|
var color2 = new Color( 0, 1, 0 );
|
|
|
|
for ( var i = 0; i < this.bones.length; i ++ ) {
|
|
|
|
var bone = this.bones[ i ];
|
|
|
|
if ( bone.parent && bone.parent.isBone ) {
|
|
|
|
vertices.push( 0, 0, 0 );
|
|
vertices.push( 0, 0, 0 );
|
|
colors.push( color1.r, color1.g, color1.b );
|
|
colors.push( color2.r, color2.g, color2.b );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );
|
|
|
|
LineSegments.call( this, geometry, material );
|
|
|
|
this.root = object;
|
|
|
|
this.matrix = object.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
|
|
SkeletonHelper.prototype = Object.create( LineSegments.prototype );
|
|
SkeletonHelper.prototype.constructor = SkeletonHelper;
|
|
|
|
SkeletonHelper.prototype.getBoneList = function( object ) {
|
|
|
|
var boneList = [];
|
|
|
|
if ( object && object.isBone ) {
|
|
|
|
boneList.push( object );
|
|
|
|
}
|
|
|
|
for ( var i = 0; i < object.children.length; i ++ ) {
|
|
|
|
boneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );
|
|
|
|
}
|
|
|
|
return boneList;
|
|
|
|
};
|
|
|
|
SkeletonHelper.prototype.update = function () {
|
|
|
|
var vector = new Vector3();
|
|
|
|
var boneMatrix = new Matrix4();
|
|
var matrixWorldInv = new Matrix4();
|
|
|
|
return function update() {
|
|
|
|
var geometry = this.geometry;
|
|
var position = geometry.getAttribute( 'position' );
|
|
|
|
matrixWorldInv.getInverse( this.root.matrixWorld );
|
|
|
|
for ( var i = 0, j = 0; i < this.bones.length; i ++ ) {
|
|
|
|
var bone = this.bones[ i ];
|
|
|
|
if ( bone.parent && bone.parent.isBone ) {
|
|
|
|
boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );
|
|
vector.setFromMatrixPosition( boneMatrix );
|
|
position.setXYZ( j, vector.x, vector.y, vector.z );
|
|
|
|
boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );
|
|
vector.setFromMatrixPosition( boneMatrix );
|
|
position.setXYZ( j + 1, vector.x, vector.y, vector.z );
|
|
|
|
j += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.getAttribute( 'position' ).needsUpdate = true;
|
|
|
|
};
|
|
|
|
}();
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function PointLightHelper( light, sphereSize ) {
|
|
|
|
this.light = light;
|
|
this.light.updateMatrixWorld();
|
|
|
|
var geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
|
|
var material = new MeshBasicMaterial( { wireframe: true, fog: false } );
|
|
material.color.copy( this.light.color );
|
|
|
|
Mesh.call( this, geometry, material );
|
|
|
|
this.matrix = this.light.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
/*
|
|
var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );
|
|
var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
|
|
|
|
this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
|
|
this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
|
|
|
|
var d = light.distance;
|
|
|
|
if ( d === 0.0 ) {
|
|
|
|
this.lightDistance.visible = false;
|
|
|
|
} else {
|
|
|
|
this.lightDistance.scale.set( d, d, d );
|
|
|
|
}
|
|
|
|
this.add( this.lightDistance );
|
|
*/
|
|
|
|
}
|
|
|
|
PointLightHelper.prototype = Object.create( Mesh.prototype );
|
|
PointLightHelper.prototype.constructor = PointLightHelper;
|
|
|
|
PointLightHelper.prototype.dispose = function () {
|
|
|
|
this.geometry.dispose();
|
|
this.material.dispose();
|
|
|
|
};
|
|
|
|
PointLightHelper.prototype.update = function () {
|
|
|
|
this.material.color.copy( this.light.color );
|
|
|
|
/*
|
|
var d = this.light.distance;
|
|
|
|
if ( d === 0.0 ) {
|
|
|
|
this.lightDistance.visible = false;
|
|
|
|
} else {
|
|
|
|
this.lightDistance.visible = true;
|
|
this.lightDistance.scale.set( d, d, d );
|
|
|
|
}
|
|
*/
|
|
|
|
};
|
|
|
|
/**
|
|
* @author abelnation / http://github.com/abelnation
|
|
* @author Mugen87 / http://github.com/Mugen87
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function RectAreaLightHelper( light ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.light = light;
|
|
this.light.updateMatrixWorld();
|
|
|
|
this.matrix = light.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
var material = new LineBasicMaterial( { color: light.color } );
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) );
|
|
|
|
this.add( new Line( geometry, material ) );
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
RectAreaLightHelper.prototype = Object.create( Object3D.prototype );
|
|
RectAreaLightHelper.prototype.constructor = RectAreaLightHelper;
|
|
|
|
RectAreaLightHelper.prototype.dispose = function () {
|
|
|
|
this.children[ 0 ].geometry.dispose();
|
|
this.children[ 0 ].material.dispose();
|
|
|
|
};
|
|
|
|
RectAreaLightHelper.prototype.update = function () {
|
|
|
|
var line = this.children[ 0 ];
|
|
|
|
// update material
|
|
|
|
line.material.color.copy( this.light.color );
|
|
|
|
// calculate new dimensions of the helper
|
|
|
|
var hx = this.light.width * 0.5;
|
|
var hy = this.light.height * 0.5;
|
|
|
|
var position = line.geometry.attributes.position;
|
|
var array = position.array;
|
|
|
|
// update vertices
|
|
|
|
array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;
|
|
array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;
|
|
array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;
|
|
array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0;
|
|
array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0;
|
|
|
|
position.needsUpdate = true;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*/
|
|
|
|
function HemisphereLightHelper( light, size ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.light = light;
|
|
this.light.updateMatrixWorld();
|
|
|
|
this.matrix = light.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
var geometry = new OctahedronBufferGeometry( size );
|
|
geometry.rotateY( Math.PI * 0.5 );
|
|
|
|
var material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );
|
|
|
|
var position = geometry.getAttribute( 'position' );
|
|
var colors = new Float32Array( position.count * 3 );
|
|
|
|
geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );
|
|
|
|
this.add( new Mesh( geometry, material ) );
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
HemisphereLightHelper.prototype = Object.create( Object3D.prototype );
|
|
HemisphereLightHelper.prototype.constructor = HemisphereLightHelper;
|
|
|
|
HemisphereLightHelper.prototype.dispose = function () {
|
|
|
|
this.children[ 0 ].geometry.dispose();
|
|
this.children[ 0 ].material.dispose();
|
|
|
|
};
|
|
|
|
HemisphereLightHelper.prototype.update = function () {
|
|
|
|
var vector = new Vector3();
|
|
|
|
var color1 = new Color();
|
|
var color2 = new Color();
|
|
|
|
return function update() {
|
|
|
|
var mesh = this.children[ 0 ];
|
|
|
|
var colors = mesh.geometry.getAttribute( 'color' );
|
|
|
|
color1.copy( this.light.color );
|
|
color2.copy( this.light.groundColor );
|
|
|
|
for ( var i = 0, l = colors.count; i < l; i ++ ) {
|
|
|
|
var color = ( i < ( l / 2 ) ) ? color1 : color2;
|
|
|
|
colors.setXYZ( i, color.r, color.g, color.b );
|
|
|
|
}
|
|
|
|
mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );
|
|
|
|
colors.needsUpdate = true;
|
|
|
|
};
|
|
|
|
}();
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function GridHelper( size, divisions, color1, color2 ) {
|
|
|
|
size = size || 10;
|
|
divisions = divisions || 10;
|
|
color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
|
|
color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
|
|
|
|
var center = divisions / 2;
|
|
var step = size / divisions;
|
|
var halfSize = size / 2;
|
|
|
|
var vertices = [], colors = [];
|
|
|
|
for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
|
|
|
|
vertices.push( - halfSize, 0, k, halfSize, 0, k );
|
|
vertices.push( k, 0, - halfSize, k, 0, halfSize );
|
|
|
|
var color = i === center ? color1 : color2;
|
|
|
|
color.toArray( colors, j ); j += 3;
|
|
color.toArray( colors, j ); j += 3;
|
|
color.toArray( colors, j ); j += 3;
|
|
color.toArray( colors, j ); j += 3;
|
|
|
|
}
|
|
|
|
var geometry = new BufferGeometry();
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
|
|
|
|
LineSegments.call( this, geometry, material );
|
|
|
|
}
|
|
|
|
GridHelper.prototype = Object.create( LineSegments.prototype );
|
|
GridHelper.prototype.constructor = GridHelper;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / http://github.com/Mugen87
|
|
* @author Hectate / http://www.github.com/Hectate
|
|
*/
|
|
|
|
function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
|
|
|
|
radius = radius || 10;
|
|
radials = radials || 16;
|
|
circles = circles || 8;
|
|
divisions = divisions || 64;
|
|
color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
|
|
color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
|
|
|
|
var vertices = [];
|
|
var colors = [];
|
|
|
|
var x, z;
|
|
var v, i, j, r, color;
|
|
|
|
// create the radials
|
|
|
|
for ( i = 0; i <= radials; i ++ ) {
|
|
|
|
v = ( i / radials ) * ( Math.PI * 2 );
|
|
|
|
x = Math.sin( v ) * radius;
|
|
z = Math.cos( v ) * radius;
|
|
|
|
vertices.push( 0, 0, 0 );
|
|
vertices.push( x, 0, z );
|
|
|
|
color = ( i & 1 ) ? color1 : color2;
|
|
|
|
colors.push( color.r, color.g, color.b );
|
|
colors.push( color.r, color.g, color.b );
|
|
|
|
}
|
|
|
|
// create the circles
|
|
|
|
for ( i = 0; i <= circles; i ++ ) {
|
|
|
|
color = ( i & 1 ) ? color1 : color2;
|
|
|
|
r = radius - ( radius / circles * i );
|
|
|
|
for ( j = 0; j < divisions; j ++ ) {
|
|
|
|
// first vertex
|
|
|
|
v = ( j / divisions ) * ( Math.PI * 2 );
|
|
|
|
x = Math.sin( v ) * r;
|
|
z = Math.cos( v ) * r;
|
|
|
|
vertices.push( x, 0, z );
|
|
colors.push( color.r, color.g, color.b );
|
|
|
|
// second vertex
|
|
|
|
v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
|
|
|
|
x = Math.sin( v ) * r;
|
|
z = Math.cos( v ) * r;
|
|
|
|
vertices.push( x, 0, z );
|
|
colors.push( color.r, color.g, color.b );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var geometry = new BufferGeometry();
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
|
|
|
|
LineSegments.call( this, geometry, material );
|
|
|
|
}
|
|
|
|
PolarGridHelper.prototype = Object.create( LineSegments.prototype );
|
|
PolarGridHelper.prototype.constructor = PolarGridHelper;
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function FaceNormalsHelper( object, size, hex, linewidth ) {
|
|
|
|
// FaceNormalsHelper only supports THREE.Geometry
|
|
|
|
this.object = object;
|
|
|
|
this.size = ( size !== undefined ) ? size : 1;
|
|
|
|
var color = ( hex !== undefined ) ? hex : 0xffff00;
|
|
|
|
var width = ( linewidth !== undefined ) ? linewidth : 1;
|
|
|
|
//
|
|
|
|
var nNormals = 0;
|
|
|
|
var objGeometry = this.object.geometry;
|
|
|
|
if ( objGeometry && objGeometry.isGeometry ) {
|
|
|
|
nNormals = objGeometry.faces.length;
|
|
|
|
} else {
|
|
|
|
console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var geometry = new BufferGeometry();
|
|
|
|
var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
|
|
|
|
geometry.addAttribute( 'position', positions );
|
|
|
|
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );
|
|
|
|
//
|
|
|
|
this.matrixAutoUpdate = false;
|
|
this.update();
|
|
|
|
}
|
|
|
|
FaceNormalsHelper.prototype = Object.create( LineSegments.prototype );
|
|
FaceNormalsHelper.prototype.constructor = FaceNormalsHelper;
|
|
|
|
FaceNormalsHelper.prototype.update = ( function () {
|
|
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
var normalMatrix = new Matrix3();
|
|
|
|
return function update() {
|
|
|
|
this.object.updateMatrixWorld( true );
|
|
|
|
normalMatrix.getNormalMatrix( this.object.matrixWorld );
|
|
|
|
var matrixWorld = this.object.matrixWorld;
|
|
|
|
var position = this.geometry.attributes.position;
|
|
|
|
//
|
|
|
|
var objGeometry = this.object.geometry;
|
|
|
|
var vertices = objGeometry.vertices;
|
|
|
|
var faces = objGeometry.faces;
|
|
|
|
var idx = 0;
|
|
|
|
for ( var i = 0, l = faces.length; i < l; i ++ ) {
|
|
|
|
var face = faces[ i ];
|
|
|
|
var normal = face.normal;
|
|
|
|
v1.copy( vertices[ face.a ] )
|
|
.add( vertices[ face.b ] )
|
|
.add( vertices[ face.c ] )
|
|
.divideScalar( 3 )
|
|
.applyMatrix4( matrixWorld );
|
|
|
|
v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
|
|
|
|
position.setXYZ( idx, v1.x, v1.y, v1.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
position.setXYZ( idx, v2.x, v2.y, v2.z );
|
|
|
|
idx = idx + 1;
|
|
|
|
}
|
|
|
|
position.needsUpdate = true;
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
*/
|
|
|
|
function DirectionalLightHelper( light, size ) {
|
|
|
|
Object3D.call( this );
|
|
|
|
this.light = light;
|
|
this.light.updateMatrixWorld();
|
|
|
|
this.matrix = light.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
if ( size === undefined ) size = 1;
|
|
|
|
var geometry = new BufferGeometry();
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( [
|
|
- size, size, 0,
|
|
size, size, 0,
|
|
size, - size, 0,
|
|
- size, - size, 0,
|
|
- size, size, 0
|
|
], 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { fog: false } );
|
|
|
|
this.add( new Line( geometry, material ) );
|
|
|
|
geometry = new BufferGeometry();
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
|
|
|
|
this.add( new Line( geometry, material ));
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
DirectionalLightHelper.prototype = Object.create( Object3D.prototype );
|
|
DirectionalLightHelper.prototype.constructor = DirectionalLightHelper;
|
|
|
|
DirectionalLightHelper.prototype.dispose = function () {
|
|
|
|
var lightPlane = this.children[ 0 ];
|
|
var targetLine = this.children[ 1 ];
|
|
|
|
lightPlane.geometry.dispose();
|
|
lightPlane.material.dispose();
|
|
targetLine.geometry.dispose();
|
|
targetLine.material.dispose();
|
|
|
|
};
|
|
|
|
DirectionalLightHelper.prototype.update = function () {
|
|
|
|
var v1 = new Vector3();
|
|
var v2 = new Vector3();
|
|
var v3 = new Vector3();
|
|
|
|
return function update() {
|
|
|
|
v1.setFromMatrixPosition( this.light.matrixWorld );
|
|
v2.setFromMatrixPosition( this.light.target.matrixWorld );
|
|
v3.subVectors( v2, v1 );
|
|
|
|
var lightPlane = this.children[ 0 ];
|
|
var targetLine = this.children[ 1 ];
|
|
|
|
lightPlane.lookAt( v3 );
|
|
lightPlane.material.color.copy( this.light.color );
|
|
|
|
targetLine.lookAt( v3 );
|
|
targetLine.scale.z = v3.length();
|
|
|
|
};
|
|
|
|
}();
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author Mugen87 / https://github.com/Mugen87
|
|
*
|
|
* - shows frustum, line of sight and up of the camera
|
|
* - suitable for fast updates
|
|
* - based on frustum visualization in lightgl.js shadowmap example
|
|
* http://evanw.github.com/lightgl.js/tests/shadowmap.html
|
|
*/
|
|
|
|
function CameraHelper( camera ) {
|
|
|
|
var geometry = new BufferGeometry();
|
|
var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );
|
|
|
|
var vertices = [];
|
|
var colors = [];
|
|
|
|
var pointMap = {};
|
|
|
|
// colors
|
|
|
|
var colorFrustum = new Color( 0xffaa00 );
|
|
var colorCone = new Color( 0xff0000 );
|
|
var colorUp = new Color( 0x00aaff );
|
|
var colorTarget = new Color( 0xffffff );
|
|
var colorCross = new Color( 0x333333 );
|
|
|
|
// near
|
|
|
|
addLine( "n1", "n2", colorFrustum );
|
|
addLine( "n2", "n4", colorFrustum );
|
|
addLine( "n4", "n3", colorFrustum );
|
|
addLine( "n3", "n1", colorFrustum );
|
|
|
|
// far
|
|
|
|
addLine( "f1", "f2", colorFrustum );
|
|
addLine( "f2", "f4", colorFrustum );
|
|
addLine( "f4", "f3", colorFrustum );
|
|
addLine( "f3", "f1", colorFrustum );
|
|
|
|
// sides
|
|
|
|
addLine( "n1", "f1", colorFrustum );
|
|
addLine( "n2", "f2", colorFrustum );
|
|
addLine( "n3", "f3", colorFrustum );
|
|
addLine( "n4", "f4", colorFrustum );
|
|
|
|
// cone
|
|
|
|
addLine( "p", "n1", colorCone );
|
|
addLine( "p", "n2", colorCone );
|
|
addLine( "p", "n3", colorCone );
|
|
addLine( "p", "n4", colorCone );
|
|
|
|
// up
|
|
|
|
addLine( "u1", "u2", colorUp );
|
|
addLine( "u2", "u3", colorUp );
|
|
addLine( "u3", "u1", colorUp );
|
|
|
|
// target
|
|
|
|
addLine( "c", "t", colorTarget );
|
|
addLine( "p", "c", colorCross );
|
|
|
|
// cross
|
|
|
|
addLine( "cn1", "cn2", colorCross );
|
|
addLine( "cn3", "cn4", colorCross );
|
|
|
|
addLine( "cf1", "cf2", colorCross );
|
|
addLine( "cf3", "cf4", colorCross );
|
|
|
|
function addLine( a, b, color ) {
|
|
|
|
addPoint( a, color );
|
|
addPoint( b, color );
|
|
|
|
}
|
|
|
|
function addPoint( id, color ) {
|
|
|
|
vertices.push( 0, 0, 0 );
|
|
colors.push( color.r, color.g, color.b );
|
|
|
|
if ( pointMap[ id ] === undefined ) {
|
|
|
|
pointMap[ id ] = [];
|
|
|
|
}
|
|
|
|
pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
|
|
|
|
}
|
|
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
|
|
|
LineSegments.call( this, geometry, material );
|
|
|
|
this.camera = camera;
|
|
if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();
|
|
|
|
this.matrix = camera.matrixWorld;
|
|
this.matrixAutoUpdate = false;
|
|
|
|
this.pointMap = pointMap;
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
CameraHelper.prototype = Object.create( LineSegments.prototype );
|
|
CameraHelper.prototype.constructor = CameraHelper;
|
|
|
|
CameraHelper.prototype.update = function () {
|
|
|
|
var geometry, pointMap;
|
|
|
|
var vector = new Vector3();
|
|
var camera = new Camera();
|
|
|
|
function setPoint( point, x, y, z ) {
|
|
|
|
vector.set( x, y, z ).unproject( camera );
|
|
|
|
var points = pointMap[ point ];
|
|
|
|
if ( points !== undefined ) {
|
|
|
|
var position = geometry.getAttribute( 'position' );
|
|
|
|
for ( var i = 0, l = points.length; i < l; i ++ ) {
|
|
|
|
position.setXYZ( points[ i ], vector.x, vector.y, vector.z );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return function update() {
|
|
|
|
geometry = this.geometry;
|
|
pointMap = this.pointMap;
|
|
|
|
var w = 1, h = 1;
|
|
|
|
// we need just camera projection matrix
|
|
// world matrix must be identity
|
|
|
|
camera.projectionMatrix.copy( this.camera.projectionMatrix );
|
|
|
|
// center / target
|
|
|
|
setPoint( "c", 0, 0, - 1 );
|
|
setPoint( "t", 0, 0, 1 );
|
|
|
|
// near
|
|
|
|
setPoint( "n1", - w, - h, - 1 );
|
|
setPoint( "n2", w, - h, - 1 );
|
|
setPoint( "n3", - w, h, - 1 );
|
|
setPoint( "n4", w, h, - 1 );
|
|
|
|
// far
|
|
|
|
setPoint( "f1", - w, - h, 1 );
|
|
setPoint( "f2", w, - h, 1 );
|
|
setPoint( "f3", - w, h, 1 );
|
|
setPoint( "f4", w, h, 1 );
|
|
|
|
// up
|
|
|
|
setPoint( "u1", w * 0.7, h * 1.1, - 1 );
|
|
setPoint( "u2", - w * 0.7, h * 1.1, - 1 );
|
|
setPoint( "u3", 0, h * 2, - 1 );
|
|
|
|
// cross
|
|
|
|
setPoint( "cf1", - w, 0, 1 );
|
|
setPoint( "cf2", w, 0, 1 );
|
|
setPoint( "cf3", 0, - h, 1 );
|
|
setPoint( "cf4", 0, h, 1 );
|
|
|
|
setPoint( "cn1", - w, 0, - 1 );
|
|
setPoint( "cn2", w, 0, - 1 );
|
|
setPoint( "cn3", 0, - h, - 1 );
|
|
setPoint( "cn4", 0, h, - 1 );
|
|
|
|
geometry.getAttribute( 'position' ).needsUpdate = true;
|
|
|
|
};
|
|
|
|
}();
|
|
|
|
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
* @author Mugen87 / http://github.com/Mugen87
|
|
*/
|
|
|
|
function BoxHelper( object, color ) {
|
|
|
|
this.object = object;
|
|
|
|
if ( color === undefined ) color = 0xffff00;
|
|
|
|
var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
|
|
var positions = new Float32Array( 8 * 3 );
|
|
|
|
var geometry = new BufferGeometry();
|
|
geometry.setIndex( new BufferAttribute( indices, 1 ) );
|
|
geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
|
|
|
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );
|
|
|
|
this.matrixAutoUpdate = false;
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
BoxHelper.prototype = Object.create( LineSegments.prototype );
|
|
BoxHelper.prototype.constructor = BoxHelper;
|
|
|
|
BoxHelper.prototype.update = ( function () {
|
|
|
|
var box = new Box3();
|
|
|
|
return function update( object ) {
|
|
|
|
if ( object !== undefined ) {
|
|
|
|
console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
|
|
|
|
}
|
|
|
|
if ( this.object !== undefined ) {
|
|
|
|
box.setFromObject( this.object );
|
|
|
|
}
|
|
|
|
if ( box.isEmpty() ) return;
|
|
|
|
var min = box.min;
|
|
var max = box.max;
|
|
|
|
/*
|
|
5____4
|
|
1/___0/|
|
|
| 6__|_7
|
|
2/___3/
|
|
|
|
0: max.x, max.y, max.z
|
|
1: min.x, max.y, max.z
|
|
2: min.x, min.y, max.z
|
|
3: max.x, min.y, max.z
|
|
4: max.x, max.y, min.z
|
|
5: min.x, max.y, min.z
|
|
6: min.x, min.y, min.z
|
|
7: max.x, min.y, min.z
|
|
*/
|
|
|
|
var position = this.geometry.attributes.position;
|
|
var array = position.array;
|
|
|
|
array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
|
|
array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
|
|
array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
|
|
array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
|
|
array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
|
|
array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
|
|
array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
|
|
array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
|
|
|
|
position.needsUpdate = true;
|
|
|
|
this.geometry.computeBoundingSphere();
|
|
|
|
};
|
|
|
|
} )();
|
|
|
|
BoxHelper.prototype.setFromObject = function ( object ) {
|
|
|
|
this.object = object;
|
|
this.update();
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* @author WestLangley / http://github.com/WestLangley
|
|
* @author zz85 / http://github.com/zz85
|
|
* @author bhouston / http://clara.io
|
|
*
|
|
* Creates an arrow for visualizing directions
|
|
*
|
|
* Parameters:
|
|
* dir - Vector3
|
|
* origin - Vector3
|
|
* length - Number
|
|
* color - color in hex value
|
|
* headLength - Number
|
|
* headWidth - Number
|
|
*/
|
|
|
|
var lineGeometry;
|
|
var coneGeometry;
|
|
|
|
function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
|
|
|
|
// dir is assumed to be normalized
|
|
|
|
Object3D.call( this );
|
|
|
|
if ( color === undefined ) color = 0xffff00;
|
|
if ( length === undefined ) length = 1;
|
|
if ( headLength === undefined ) headLength = 0.2 * length;
|
|
if ( headWidth === undefined ) headWidth = 0.2 * headLength;
|
|
|
|
if ( lineGeometry === undefined ) {
|
|
|
|
lineGeometry = new BufferGeometry();
|
|
lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
|
|
|
|
coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
|
|
coneGeometry.translate( 0, - 0.5, 0 );
|
|
|
|
}
|
|
|
|
this.position.copy( origin );
|
|
|
|
this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );
|
|
this.line.matrixAutoUpdate = false;
|
|
this.add( this.line );
|
|
|
|
this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );
|
|
this.cone.matrixAutoUpdate = false;
|
|
this.add( this.cone );
|
|
|
|
this.setDirection( dir );
|
|
this.setLength( length, headLength, headWidth );
|
|
|
|
}
|
|
|
|
ArrowHelper.prototype = Object.create( Object3D.prototype );
|
|
ArrowHelper.prototype.constructor = ArrowHelper;
|
|
|
|
ArrowHelper.prototype.setDirection = ( function () {
|
|
|
|
var axis = new Vector3();
|
|
var radians;
|
|
|
|
return function setDirection( dir ) {
|
|
|
|
// dir is assumed to be normalized
|
|
|
|
if ( dir.y > 0.99999 ) {
|
|
|
|
this.quaternion.set( 0, 0, 0, 1 );
|
|
|
|
} else if ( dir.y < - 0.99999 ) {
|
|
|
|
this.quaternion.set( 1, 0, 0, 0 );
|
|
|
|
} else {
|
|
|
|
axis.set( dir.z, 0, - dir.x ).normalize();
|
|
|
|
radians = Math.acos( dir.y );
|
|
|
|
this.quaternion.setFromAxisAngle( axis, radians );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
|
|
|
|
if ( headLength === undefined ) headLength = 0.2 * length;
|
|
if ( headWidth === undefined ) headWidth = 0.2 * headLength;
|
|
|
|
this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );
|
|
this.line.updateMatrix();
|
|
|
|
this.cone.scale.set( headWidth, headLength, headWidth );
|
|
this.cone.position.y = length;
|
|
this.cone.updateMatrix();
|
|
|
|
};
|
|
|
|
ArrowHelper.prototype.setColor = function ( color ) {
|
|
|
|
this.line.material.color.copy( color );
|
|
this.cone.material.color.copy( color );
|
|
|
|
};
|
|
|
|
/**
|
|
* @author sroucheray / http://sroucheray.org/
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
function AxisHelper( size ) {
|
|
|
|
size = size || 1;
|
|
|
|
var vertices = [
|
|
0, 0, 0, size, 0, 0,
|
|
0, 0, 0, 0, size, 0,
|
|
0, 0, 0, 0, 0, size
|
|
];
|
|
|
|
var colors = [
|
|
1, 0, 0, 1, 0.6, 0,
|
|
0, 1, 0, 0.6, 1, 0,
|
|
0, 0, 1, 0, 0.6, 1
|
|
];
|
|
|
|
var geometry = new BufferGeometry();
|
|
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
|
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
|
|
|
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
|
|
|
|
LineSegments.call( this, geometry, material );
|
|
|
|
}
|
|
|
|
AxisHelper.prototype = Object.create( LineSegments.prototype );
|
|
AxisHelper.prototype.constructor = AxisHelper;
|
|
|
|
/**
|
|
* @author zz85 https://github.com/zz85
|
|
*
|
|
* Centripetal CatmullRom Curve - which is useful for avoiding
|
|
* cusps and self-intersections in non-uniform catmull rom curves.
|
|
* http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
|
|
*
|
|
* curve.type accepts centripetal(default), chordal and catmullrom
|
|
* curve.tension is used for catmullrom which defaults to 0.5
|
|
*/
|
|
|
|
|
|
/*
|
|
Based on an optimized c++ solution in
|
|
- http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
|
|
- http://ideone.com/NoEbVM
|
|
|
|
This CubicPoly class could be used for reusing some variables and calculations,
|
|
but for three.js curve use, it could be possible inlined and flatten into a single function call
|
|
which can be placed in CurveUtils.
|
|
*/
|
|
|
|
function CubicPoly() {
|
|
|
|
var c0 = 0, c1 = 0, c2 = 0, c3 = 0;
|
|
|
|
/*
|
|
* Compute coefficients for a cubic polynomial
|
|
* p(s) = c0 + c1*s + c2*s^2 + c3*s^3
|
|
* such that
|
|
* p(0) = x0, p(1) = x1
|
|
* and
|
|
* p'(0) = t0, p'(1) = t1.
|
|
*/
|
|
function init( x0, x1, t0, t1 ) {
|
|
|
|
c0 = x0;
|
|
c1 = t0;
|
|
c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
|
|
c3 = 2 * x0 - 2 * x1 + t0 + t1;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
initCatmullRom: function ( x0, x1, x2, x3, tension ) {
|
|
|
|
init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
|
|
|
|
},
|
|
|
|
initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
|
|
|
|
// compute tangents when parameterized in [t1,t2]
|
|
var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
|
|
var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
|
|
|
|
// rescale tangents for parametrization in [0,1]
|
|
t1 *= dt1;
|
|
t2 *= dt1;
|
|
|
|
init( x1, x2, t1, t2 );
|
|
|
|
},
|
|
|
|
calc: function ( t ) {
|
|
|
|
var t2 = t * t;
|
|
var t3 = t2 * t;
|
|
return c0 + c1 * t + c2 * t2 + c3 * t3;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
//
|
|
|
|
var tmp = new Vector3();
|
|
var px = new CubicPoly();
|
|
var py = new CubicPoly();
|
|
var pz = new CubicPoly();
|
|
|
|
function CatmullRomCurve3( p /* array of Vector3 */ ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.points = p || [];
|
|
this.closed = false;
|
|
|
|
}
|
|
|
|
CatmullRomCurve3.prototype = Object.create( Curve.prototype );
|
|
CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
|
|
|
|
CatmullRomCurve3.prototype.getPoint = function ( t ) {
|
|
|
|
var points = this.points;
|
|
var l = points.length;
|
|
|
|
if ( l < 2 ) console.log( 'duh, you need at least 2 points' );
|
|
|
|
var point = ( l - ( this.closed ? 0 : 1 ) ) * t;
|
|
var intPoint = Math.floor( point );
|
|
var weight = point - intPoint;
|
|
|
|
if ( this.closed ) {
|
|
|
|
intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
|
|
|
|
} else if ( weight === 0 && intPoint === l - 1 ) {
|
|
|
|
intPoint = l - 2;
|
|
weight = 1;
|
|
|
|
}
|
|
|
|
var p0, p1, p2, p3; // 4 points
|
|
|
|
if ( this.closed || intPoint > 0 ) {
|
|
|
|
p0 = points[ ( intPoint - 1 ) % l ];
|
|
|
|
} else {
|
|
|
|
// extrapolate first point
|
|
tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
|
|
p0 = tmp;
|
|
|
|
}
|
|
|
|
p1 = points[ intPoint % l ];
|
|
p2 = points[ ( intPoint + 1 ) % l ];
|
|
|
|
if ( this.closed || intPoint + 2 < l ) {
|
|
|
|
p3 = points[ ( intPoint + 2 ) % l ];
|
|
|
|
} else {
|
|
|
|
// extrapolate last point
|
|
tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
|
|
p3 = tmp;
|
|
|
|
}
|
|
|
|
if ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {
|
|
|
|
// init Centripetal / Chordal Catmull-Rom
|
|
var pow = this.type === 'chordal' ? 0.5 : 0.25;
|
|
var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
|
|
var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
|
|
var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
|
|
|
|
// safety check for repeated points
|
|
if ( dt1 < 1e-4 ) dt1 = 1.0;
|
|
if ( dt0 < 1e-4 ) dt0 = dt1;
|
|
if ( dt2 < 1e-4 ) dt2 = dt1;
|
|
|
|
px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
|
|
py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
|
|
pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
|
|
|
|
} else if ( this.type === 'catmullrom' ) {
|
|
|
|
var tension = this.tension !== undefined ? this.tension : 0.5;
|
|
px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );
|
|
py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );
|
|
pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );
|
|
|
|
}
|
|
|
|
return new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );
|
|
|
|
};
|
|
|
|
function CubicBezierCurve3( v0, v1, v2, v3 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v0 = v0;
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
this.v3 = v3;
|
|
|
|
}
|
|
|
|
CubicBezierCurve3.prototype = Object.create( Curve.prototype );
|
|
CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
|
|
|
|
CubicBezierCurve3.prototype.getPoint = function ( t ) {
|
|
|
|
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
|
|
|
return new Vector3(
|
|
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
|
CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
|
|
CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
|
|
);
|
|
|
|
};
|
|
|
|
function QuadraticBezierCurve3( v0, v1, v2 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v0 = v0;
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
|
|
}
|
|
|
|
QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
|
|
QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
|
|
|
|
QuadraticBezierCurve3.prototype.getPoint = function ( t ) {
|
|
|
|
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
|
|
|
return new Vector3(
|
|
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
|
QuadraticBezier( t, v0.y, v1.y, v2.y ),
|
|
QuadraticBezier( t, v0.z, v1.z, v2.z )
|
|
);
|
|
|
|
};
|
|
|
|
function LineCurve3( v1, v2 ) {
|
|
|
|
Curve.call( this );
|
|
|
|
this.v1 = v1;
|
|
this.v2 = v2;
|
|
|
|
}
|
|
|
|
LineCurve3.prototype = Object.create( Curve.prototype );
|
|
LineCurve3.prototype.constructor = LineCurve3;
|
|
|
|
LineCurve3.prototype.getPoint = function ( t ) {
|
|
|
|
if ( t === 1 ) {
|
|
|
|
return this.v2.clone();
|
|
|
|
}
|
|
|
|
var vector = new Vector3();
|
|
|
|
vector.subVectors( this.v2, this.v1 ); // diff
|
|
vector.multiplyScalar( t );
|
|
vector.add( this.v1 );
|
|
|
|
return vector;
|
|
|
|
};
|
|
|
|
function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
|
|
|
EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
|
|
|
|
}
|
|
|
|
ArcCurve.prototype = Object.create( EllipseCurve.prototype );
|
|
ArcCurve.prototype.constructor = ArcCurve;
|
|
|
|
//
|
|
|
|
Curve.create = function ( construct, getPoint ) {
|
|
|
|
console.log( 'THREE.Curve.create() has been deprecated' );
|
|
|
|
construct.prototype = Object.create( Curve.prototype );
|
|
construct.prototype.constructor = construct;
|
|
construct.prototype.getPoint = getPoint;
|
|
|
|
return construct;
|
|
|
|
};
|
|
|
|
//
|
|
|
|
function Spline( points ) {
|
|
|
|
console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );
|
|
|
|
CatmullRomCurve3.call( this, points );
|
|
this.type = 'catmullrom';
|
|
|
|
}
|
|
|
|
Spline.prototype = Object.create( CatmullRomCurve3.prototype );
|
|
|
|
Object.assign( Spline.prototype, {
|
|
|
|
initFromArray: function ( a ) {
|
|
|
|
console.error( 'THREE.Spline: .initFromArray() has been removed.' );
|
|
|
|
},
|
|
getControlPointsArray: function ( optionalTarget ) {
|
|
|
|
console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
|
|
|
|
},
|
|
reparametrizeByArcLength: function ( samplingCoef ) {
|
|
|
|
console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
GridHelper.prototype.setColors = function () {
|
|
|
|
console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );
|
|
|
|
};
|
|
|
|
//
|
|
|
|
Object.assign( Box2.prototype, {
|
|
|
|
center: function ( optionalTarget ) {
|
|
|
|
console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
|
|
return this.getCenter( optionalTarget );
|
|
|
|
},
|
|
empty: function () {
|
|
|
|
console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );
|
|
return this.isEmpty();
|
|
|
|
},
|
|
isIntersectionBox: function ( box ) {
|
|
|
|
console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );
|
|
return this.intersectsBox( box );
|
|
|
|
},
|
|
size: function ( optionalTarget ) {
|
|
|
|
console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
|
|
return this.getSize( optionalTarget );
|
|
|
|
}
|
|
} );
|
|
|
|
Object.assign( Box3.prototype, {
|
|
|
|
center: function ( optionalTarget ) {
|
|
|
|
console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );
|
|
return this.getCenter( optionalTarget );
|
|
|
|
},
|
|
empty: function () {
|
|
|
|
console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );
|
|
return this.isEmpty();
|
|
|
|
},
|
|
isIntersectionBox: function ( box ) {
|
|
|
|
console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );
|
|
return this.intersectsBox( box );
|
|
|
|
},
|
|
isIntersectionSphere: function ( sphere ) {
|
|
|
|
console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
|
|
return this.intersectsSphere( sphere );
|
|
|
|
},
|
|
size: function ( optionalTarget ) {
|
|
|
|
console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );
|
|
return this.getSize( optionalTarget );
|
|
|
|
}
|
|
} );
|
|
|
|
Line3.prototype.center = function ( optionalTarget ) {
|
|
|
|
console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );
|
|
return this.getCenter( optionalTarget );
|
|
|
|
};
|
|
|
|
_Math.random16 = function () {
|
|
|
|
console.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );
|
|
return Math.random();
|
|
|
|
};
|
|
|
|
Object.assign( Matrix3.prototype, {
|
|
|
|
flattenToArrayOffset: function ( array, offset ) {
|
|
|
|
console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
|
|
return this.toArray( array, offset );
|
|
|
|
},
|
|
multiplyVector3: function ( vector ) {
|
|
|
|
console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
|
|
return vector.applyMatrix3( this );
|
|
|
|
},
|
|
multiplyVector3Array: function ( a ) {
|
|
|
|
console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
|
|
return this.applyToVector3Array( a );
|
|
|
|
},
|
|
applyToBuffer: function( buffer, offset, length ) {
|
|
|
|
console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
|
|
return this.applyToBufferAttribute( buffer );
|
|
|
|
},
|
|
applyToVector3Array: function( array, offset, length ) {
|
|
|
|
console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Matrix4.prototype, {
|
|
|
|
extractPosition: function ( m ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
|
|
return this.copyPosition( m );
|
|
|
|
},
|
|
flattenToArrayOffset: function ( array, offset ) {
|
|
|
|
console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
|
|
return this.toArray( array, offset );
|
|
|
|
},
|
|
getPosition: function () {
|
|
|
|
var v1;
|
|
|
|
return function getPosition() {
|
|
|
|
if ( v1 === undefined ) v1 = new Vector3();
|
|
console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
|
|
return v1.setFromMatrixColumn( this, 3 );
|
|
|
|
};
|
|
|
|
}(),
|
|
setRotationFromQuaternion: function ( q ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
|
|
return this.makeRotationFromQuaternion( q );
|
|
|
|
},
|
|
multiplyToArray: function () {
|
|
|
|
console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' );
|
|
|
|
},
|
|
multiplyVector3: function ( vector ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
|
|
return vector.applyMatrix4( this );
|
|
|
|
},
|
|
multiplyVector4: function ( vector ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
|
|
return vector.applyMatrix4( this );
|
|
|
|
},
|
|
multiplyVector3Array: function ( a ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
|
|
return this.applyToVector3Array( a );
|
|
|
|
},
|
|
rotateAxis: function ( v ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
|
|
v.transformDirection( this );
|
|
|
|
},
|
|
crossVector: function ( vector ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
|
|
return vector.applyMatrix4( this );
|
|
|
|
},
|
|
translate: function () {
|
|
|
|
console.error( 'THREE.Matrix4: .translate() has been removed.' );
|
|
|
|
},
|
|
rotateX: function () {
|
|
|
|
console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
|
|
|
|
},
|
|
rotateY: function () {
|
|
|
|
console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
|
|
|
|
},
|
|
rotateZ: function () {
|
|
|
|
console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
|
|
|
|
},
|
|
rotateByAxis: function () {
|
|
|
|
console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
|
|
|
|
},
|
|
applyToBuffer: function( buffer, offset, length ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
|
|
return this.applyToBufferAttribute( buffer );
|
|
|
|
},
|
|
applyToVector3Array: function( array, offset, length ) {
|
|
|
|
console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
|
|
|
|
},
|
|
makeFrustum: function( left, right, bottom, top, near, far ) {
|
|
|
|
console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
|
|
return this.makePerspective( left, right, top, bottom, near, far );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Plane.prototype.isIntersectionLine = function ( line ) {
|
|
|
|
console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
|
|
return this.intersectsLine( line );
|
|
|
|
};
|
|
|
|
Quaternion.prototype.multiplyVector3 = function ( vector ) {
|
|
|
|
console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
|
|
return vector.applyQuaternion( this );
|
|
|
|
};
|
|
|
|
Object.assign( Ray.prototype, {
|
|
|
|
isIntersectionBox: function ( box ) {
|
|
|
|
console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );
|
|
return this.intersectsBox( box );
|
|
|
|
},
|
|
isIntersectionPlane: function ( plane ) {
|
|
|
|
console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );
|
|
return this.intersectsPlane( plane );
|
|
|
|
},
|
|
isIntersectionSphere: function ( sphere ) {
|
|
|
|
console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
|
|
return this.intersectsSphere( sphere );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Shape.prototype, {
|
|
|
|
extrude: function ( options ) {
|
|
|
|
console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );
|
|
return new ExtrudeGeometry( this, options );
|
|
|
|
},
|
|
makeGeometry: function ( options ) {
|
|
|
|
console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );
|
|
return new ShapeGeometry( this, options );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Vector2.prototype, {
|
|
|
|
fromAttribute: function ( attribute, index, offset ) {
|
|
|
|
console.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );
|
|
return this.fromBufferAttribute( attribute, index, offset );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Vector3.prototype, {
|
|
|
|
setEulerFromRotationMatrix: function () {
|
|
|
|
console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
|
|
|
|
},
|
|
setEulerFromQuaternion: function () {
|
|
|
|
console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
|
|
|
|
},
|
|
getPositionFromMatrix: function ( m ) {
|
|
|
|
console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
|
|
return this.setFromMatrixPosition( m );
|
|
|
|
},
|
|
getScaleFromMatrix: function ( m ) {
|
|
|
|
console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
|
|
return this.setFromMatrixScale( m );
|
|
|
|
},
|
|
getColumnFromMatrix: function ( index, matrix ) {
|
|
|
|
console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
|
|
return this.setFromMatrixColumn( matrix, index );
|
|
|
|
},
|
|
applyProjection: function ( m ) {
|
|
|
|
console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );
|
|
return this.applyMatrix4( m );
|
|
|
|
},
|
|
fromAttribute: function ( attribute, index, offset ) {
|
|
|
|
console.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );
|
|
return this.fromBufferAttribute( attribute, index, offset );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( Vector4.prototype, {
|
|
|
|
fromAttribute: function ( attribute, index, offset ) {
|
|
|
|
console.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );
|
|
return this.fromBufferAttribute( attribute, index, offset );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Geometry.prototype.computeTangents = function () {
|
|
|
|
console.warn( 'THREE.Geometry: .computeTangents() has been removed.' );
|
|
|
|
};
|
|
|
|
Object.assign( Object3D.prototype, {
|
|
|
|
getChildByName: function ( name ) {
|
|
|
|
console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
|
|
return this.getObjectByName( name );
|
|
|
|
},
|
|
renderDepth: function () {
|
|
|
|
console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
|
|
|
|
},
|
|
translate: function ( distance, axis ) {
|
|
|
|
console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
|
|
return this.translateOnAxis( axis, distance );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( Object3D.prototype, {
|
|
|
|
eulerOrder: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
|
|
return this.rotation.order;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
|
|
this.rotation.order = value;
|
|
|
|
}
|
|
},
|
|
useQuaternion: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
|
|
|
|
},
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( LOD.prototype, {
|
|
|
|
objects: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
|
|
return this.levels;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
|
|
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
|
|
|
|
},
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
|
|
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
|
|
return this.arcLengthDivisions;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
|
|
this.arcLengthDivisions = value;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
|
|
|
|
console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
|
|
"Use .setFocalLength and .filmGauge for a photographic setup." );
|
|
|
|
if ( filmGauge !== undefined ) this.filmGauge = filmGauge;
|
|
this.setFocalLength( focalLength );
|
|
|
|
};
|
|
|
|
//
|
|
|
|
Object.defineProperties( Light.prototype, {
|
|
onlyShadow: {
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Light: .onlyShadow has been removed.' );
|
|
|
|
}
|
|
},
|
|
shadowCameraFov: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );
|
|
this.shadow.camera.fov = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraLeft: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );
|
|
this.shadow.camera.left = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraRight: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );
|
|
this.shadow.camera.right = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraTop: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );
|
|
this.shadow.camera.top = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraBottom: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );
|
|
this.shadow.camera.bottom = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraNear: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );
|
|
this.shadow.camera.near = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraFar: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );
|
|
this.shadow.camera.far = value;
|
|
|
|
}
|
|
},
|
|
shadowCameraVisible: {
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );
|
|
|
|
}
|
|
},
|
|
shadowBias: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );
|
|
this.shadow.bias = value;
|
|
|
|
}
|
|
},
|
|
shadowDarkness: {
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
|
|
|
|
}
|
|
},
|
|
shadowMapWidth: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );
|
|
this.shadow.mapSize.width = value;
|
|
|
|
}
|
|
},
|
|
shadowMapHeight: {
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );
|
|
this.shadow.mapSize.height = value;
|
|
|
|
}
|
|
}
|
|
} );
|
|
|
|
//
|
|
|
|
Object.defineProperties( BufferAttribute.prototype, {
|
|
|
|
length: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );
|
|
return this.array.length;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
Object.assign( BufferGeometry.prototype, {
|
|
|
|
addIndex: function ( index ) {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
|
|
this.setIndex( index );
|
|
|
|
},
|
|
addDrawCall: function ( start, count, indexOffset ) {
|
|
|
|
if ( indexOffset !== undefined ) {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
|
|
|
|
}
|
|
console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
|
|
this.addGroup( start, count );
|
|
|
|
},
|
|
clearDrawCalls: function () {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
|
|
this.clearGroups();
|
|
|
|
},
|
|
computeTangents: function () {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
|
|
|
|
},
|
|
computeOffsets: function () {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( BufferGeometry.prototype, {
|
|
|
|
drawcalls: {
|
|
get: function () {
|
|
|
|
console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
|
|
return this.groups;
|
|
|
|
}
|
|
},
|
|
offsets: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
|
|
return this.groups;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Object.defineProperties( Uniform.prototype, {
|
|
|
|
dynamic: {
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
|
|
|
|
}
|
|
},
|
|
onUpdate: {
|
|
value: function () {
|
|
|
|
console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
|
|
return this;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Object.defineProperties( Material.prototype, {
|
|
|
|
wrapAround: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Material: .wrapAround has been removed.' );
|
|
|
|
},
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.Material: .wrapAround has been removed.' );
|
|
|
|
}
|
|
},
|
|
wrapRGB: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.Material: .wrapRGB has been removed.' );
|
|
return new Color();
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( MeshPhongMaterial.prototype, {
|
|
|
|
metal: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );
|
|
return false;
|
|
|
|
},
|
|
set: function () {
|
|
|
|
console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( ShaderMaterial.prototype, {
|
|
|
|
derivatives: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
|
|
return this.extensions.derivatives;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
|
|
this.extensions.derivatives = value;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Object.assign( WebGLRenderer.prototype, {
|
|
|
|
getCurrentRenderTarget: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' );
|
|
return this.getRenderTarget();
|
|
|
|
},
|
|
|
|
supportsFloatTextures: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
|
|
return this.extensions.get( 'OES_texture_float' );
|
|
|
|
},
|
|
supportsHalfFloatTextures: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
|
|
return this.extensions.get( 'OES_texture_half_float' );
|
|
|
|
},
|
|
supportsStandardDerivatives: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
|
|
return this.extensions.get( 'OES_standard_derivatives' );
|
|
|
|
},
|
|
supportsCompressedTextureS3TC: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
|
|
return this.extensions.get( 'WEBGL_compressed_texture_s3tc' );
|
|
|
|
},
|
|
supportsCompressedTexturePVRTC: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
|
|
return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );
|
|
|
|
},
|
|
supportsBlendMinMax: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
|
|
return this.extensions.get( 'EXT_blend_minmax' );
|
|
|
|
},
|
|
supportsVertexTextures: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
|
|
return this.capabilities.vertexTextures;
|
|
|
|
},
|
|
supportsInstancedArrays: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' );
|
|
return this.extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
},
|
|
enableScissorTest: function ( boolean ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );
|
|
this.setScissorTest( boolean );
|
|
|
|
},
|
|
initMaterial: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
|
|
|
|
},
|
|
addPrePlugin: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
|
|
|
|
},
|
|
addPostPlugin: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
|
|
|
|
},
|
|
updateShadowMap: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Object.defineProperties( WebGLRenderer.prototype, {
|
|
|
|
shadowMapEnabled: {
|
|
get: function () {
|
|
|
|
return this.shadowMap.enabled;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
|
|
this.shadowMap.enabled = value;
|
|
|
|
}
|
|
},
|
|
shadowMapType: {
|
|
get: function () {
|
|
|
|
return this.shadowMap.type;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
|
|
this.shadowMap.type = value;
|
|
|
|
}
|
|
},
|
|
shadowMapCullFace: {
|
|
get: function () {
|
|
|
|
return this.shadowMap.cullFace;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );
|
|
this.shadowMap.cullFace = value;
|
|
|
|
}
|
|
}
|
|
} );
|
|
|
|
Object.defineProperties( WebGLShadowMap.prototype, {
|
|
|
|
cullFace: {
|
|
get: function () {
|
|
|
|
return this.renderReverseSided ? CullFaceFront : CullFaceBack;
|
|
|
|
},
|
|
set: function ( cullFace ) {
|
|
|
|
var value = ( cullFace !== CullFaceBack );
|
|
console.warn( "WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to " + value + "." );
|
|
this.renderReverseSided = value;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Object.defineProperties( WebGLRenderTarget.prototype, {
|
|
|
|
wrapS: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
|
|
return this.texture.wrapS;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
|
|
this.texture.wrapS = value;
|
|
|
|
}
|
|
},
|
|
wrapT: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
|
|
return this.texture.wrapT;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
|
|
this.texture.wrapT = value;
|
|
|
|
}
|
|
},
|
|
magFilter: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
|
|
return this.texture.magFilter;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
|
|
this.texture.magFilter = value;
|
|
|
|
}
|
|
},
|
|
minFilter: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
|
|
return this.texture.minFilter;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
|
|
this.texture.minFilter = value;
|
|
|
|
}
|
|
},
|
|
anisotropy: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
|
|
return this.texture.anisotropy;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
|
|
this.texture.anisotropy = value;
|
|
|
|
}
|
|
},
|
|
offset: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
|
|
return this.texture.offset;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
|
|
this.texture.offset = value;
|
|
|
|
}
|
|
},
|
|
repeat: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
|
|
return this.texture.repeat;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
|
|
this.texture.repeat = value;
|
|
|
|
}
|
|
},
|
|
format: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
|
|
return this.texture.format;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
|
|
this.texture.format = value;
|
|
|
|
}
|
|
},
|
|
type: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
|
|
return this.texture.type;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
|
|
this.texture.type = value;
|
|
|
|
}
|
|
},
|
|
generateMipmaps: {
|
|
get: function () {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
|
|
return this.texture.generateMipmaps;
|
|
|
|
},
|
|
set: function ( value ) {
|
|
|
|
console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
|
|
this.texture.generateMipmaps = value;
|
|
|
|
}
|
|
}
|
|
|
|
} );
|
|
|
|
//
|
|
|
|
Audio.prototype.load = function ( file ) {
|
|
|
|
console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );
|
|
var scope = this;
|
|
var audioLoader = new AudioLoader();
|
|
audioLoader.load( file, function ( buffer ) {
|
|
|
|
scope.setBuffer( buffer );
|
|
|
|
} );
|
|
return this;
|
|
|
|
};
|
|
|
|
AudioAnalyser.prototype.getData = function () {
|
|
|
|
console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );
|
|
return this.getFrequencyData();
|
|
|
|
};
|
|
|
|
function _classCallCheck(instance, Constructor) {
|
|
if (!(instance instanceof Constructor)) {
|
|
throw new TypeError("Cannot call a class as a function");
|
|
}
|
|
}
|
|
|
|
function _defineProperties(target, props) {
|
|
for (var i = 0; i < props.length; i++) {
|
|
var descriptor = props[i];
|
|
descriptor.enumerable = descriptor.enumerable || false;
|
|
descriptor.configurable = true;
|
|
if ("value" in descriptor) descriptor.writable = true;
|
|
Object.defineProperty(target, descriptor.key, descriptor);
|
|
}
|
|
}
|
|
|
|
function _createClass(Constructor, protoProps, staticProps) {
|
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
return Constructor;
|
|
}
|
|
|
|
function _defineProperty(obj, key, value) {
|
|
if (key in obj) {
|
|
Object.defineProperty(obj, key, {
|
|
value: value,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* @class PositionalAudioModule
|
|
* @category modules/extra
|
|
* @param {Object} [params={loop: true}] - The parameters object.
|
|
* @memberof module:modules/extra
|
|
* @example <caption>How to create and apply a PositionalAudioModule</caption>
|
|
* const fogModule = const audioModule = new AudioModule({
|
|
* loop: true
|
|
* });
|
|
*
|
|
* new Sphere({
|
|
* ...,
|
|
* modules: [
|
|
* audioModule
|
|
* ]
|
|
* };
|
|
*/
|
|
|
|
var PositionalAudioModule =
|
|
/*#__PURE__*/
|
|
function () {
|
|
function PositionalAudioModule() {
|
|
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
_classCallCheck(this, PositionalAudioModule);
|
|
_defineProperty(this, "bridge", {
|
|
mesh: function mesh(_mesh, self) {
|
|
_mesh.add(self.positionalAudio);
|
|
|
|
return _mesh;
|
|
}
|
|
});
|
|
this.params = Object.assign({
|
|
loop: true
|
|
}, params);
|
|
this.audioListener = new AudioListener();
|
|
this.audioLoader = new AudioLoader();
|
|
this.positionalAudio = new PositionalAudio(this.audioListener);
|
|
this.positionalAudio.setLoop(this.params.loop);
|
|
}
|
|
/**
|
|
* @method addListener
|
|
* @description Adds the listener of this audio source, usually the camera, origin of the user perspective
|
|
* @param {Object} object The listener object
|
|
* @memberof module:modules/extra.PositionalAudioModule
|
|
*/
|
|
|
|
|
|
_createClass(PositionalAudioModule, [{
|
|
key: "addListener",
|
|
value: function addListener(object) {
|
|
object.native.add(this.audioListener);
|
|
}
|
|
/**
|
|
* @method play
|
|
* @description Plays the given sound
|
|
* @param {String} path The path to the sound file
|
|
* @memberof module:modules/extra.PositionalAudioModule
|
|
*/
|
|
|
|
}, {
|
|
key: "play",
|
|
value: function play(path) {
|
|
var sound = this.positionalAudio;
|
|
this.audioLoader.load(path, function (buffer) {
|
|
sound.setBuffer(buffer);
|
|
sound.setRefDistance(50);
|
|
sound.play();
|
|
});
|
|
}
|
|
}]);
|
|
return PositionalAudioModule;
|
|
}();
|
|
|
|
export default PositionalAudioModule;
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXVkaW9Nb2R1bGUubW9kdWxlLmpzIiwic291cmNlcyI6WyIuLi9zcmMvbW9kdWxlcy9leHRyYS9ub2RlX21vZHVsZXMvdGhyZWUvYnVpbGQvdGhyZWUubW9kdWxlLmpzIiwiLi4vc3JjL21vZHVsZXMvZXh0cmEvcm9sbHVwUGx1Z2luQmFiZWxIZWxwZXJzIiwiLi4vc3JjL21vZHVsZXMvZXh0cmEvQXVkaW9Nb2R1bGUuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gUG9seWZpbGxzXG5cbmlmICggTnVtYmVyLkVQU0lMT04gPT09IHVuZGVmaW5lZCApIHtcblxuXHROdW1iZXIuRVBTSUxPTiA9IE1hdGgucG93KCAyLCAtIDUyICk7XG5cbn1cblxuaWYgKCBOdW1iZXIuaXNJbnRlZ2VyID09PSB1bmRlZmluZWQgKSB7XG5cblx0Ly8gTWlzc2luZyBpbiBJRVxuXHQvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9OdW1iZXIvaXNJbnRlZ2VyXG5cblx0TnVtYmVyLmlzSW50ZWdlciA9IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSggdmFsdWUgKSAmJiBNYXRoLmZsb29yKCB2YWx1ZSApID09PSB2YWx1ZTtcblxuXHR9O1xuXG59XG5cbi8vXG5cbmlmICggTWF0aC5zaWduID09PSB1bmRlZmluZWQgKSB7XG5cblx0Ly8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWF0aC9zaWduXG5cblx0TWF0aC5zaWduID0gZnVuY3Rpb24gKCB4ICkge1xuXG5cdFx0cmV0dXJuICggeCA8IDAgKSA/IC0gMSA6ICggeCA+IDAgKSA/IDEgOiArIHg7XG5cblx0fTtcblxufVxuXG5pZiAoIEZ1bmN0aW9uLnByb3RvdHlwZS5uYW1lID09PSB1bmRlZmluZWQgKSB7XG5cblx0Ly8gTWlzc2luZyBpbiBJRVxuXHQvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9uYW1lXG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCBGdW5jdGlvbi5wcm90b3R5cGUsICduYW1lJywge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLnRvU3RyaW5nKCkubWF0Y2goIC9eXFxzKmZ1bmN0aW9uXFxzKihbXlxcKFxcc10qKS8gKVsgMSBdO1xuXG5cdFx0fVxuXG5cdH0gKTtcblxufVxuXG5pZiAoIE9iamVjdC5hc3NpZ24gPT09IHVuZGVmaW5lZCApIHtcblxuXHQvLyBNaXNzaW5nIGluIElFXG5cdC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9hc3NpZ25cblxuXHQoIGZ1bmN0aW9uICgpIHtcblxuXHRcdE9iamVjdC5hc3NpZ24gPSBmdW5jdGlvbiAoIHRhcmdldCApIHtcblxuXHRcdFx0J3VzZSBzdHJpY3QnO1xuXG5cdFx0XHRpZiAoIHRhcmdldCA9PT0gdW5kZWZpbmVkIHx8IHRhcmdldCA9PT0gbnVsbCApIHtcblxuXHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCAnQ2Fubm90IGNvbnZlcnQgdW5kZWZpbmVkIG9yIG51bGwgdG8gb2JqZWN0JyApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBvdXRwdXQgPSBPYmplY3QoIHRhcmdldCApO1xuXG5cdFx0XHRmb3IgKCB2YXIgaW5kZXggPSAxOyBpbmRleCA8IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4ICsrICkge1xuXG5cdFx0XHRcdHZhciBzb3VyY2UgPSBhcmd1bWVudHNbIGluZGV4IF07XG5cblx0XHRcdFx0aWYgKCBzb3VyY2UgIT09IHVuZGVmaW5lZCAmJiBzb3VyY2UgIT09IG51bGwgKSB7XG5cblx0XHRcdFx0XHRmb3IgKCB2YXIgbmV4dEtleSBpbiBzb3VyY2UgKSB7XG5cblx0XHRcdFx0XHRcdGlmICggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKCBzb3VyY2UsIG5leHRLZXkgKSApIHtcblxuXHRcdFx0XHRcdFx0XHRvdXRwdXRbIG5leHRLZXkgXSA9IHNvdXJjZVsgbmV4dEtleSBdO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvdXRwdXQ7XG5cblx0XHR9O1xuXG5cdH0gKSgpO1xuXG59XG5cbi8qKlxuICogaHR0cHM6Ly9naXRodWIuY29tL21yZG9vYi9ldmVudGRpc3BhdGNoZXIuanMvXG4gKi9cblxuZnVuY3Rpb24gRXZlbnREaXNwYXRjaGVyKCkge31cblxuT2JqZWN0LmFzc2lnbiggRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZSwge1xuXG5cdGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uICggdHlwZSwgbGlzdGVuZXIgKSB7XG5cblx0XHRpZiAoIHRoaXMuX2xpc3RlbmVycyA9PT0gdW5kZWZpbmVkICkgdGhpcy5fbGlzdGVuZXJzID0ge307XG5cblx0XHR2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzO1xuXG5cdFx0aWYgKCBsaXN0ZW5lcnNbIHR5cGUgXSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRsaXN0ZW5lcnNbIHR5cGUgXSA9IFtdO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBsaXN0ZW5lcnNbIHR5cGUgXS5pbmRleE9mKCBsaXN0ZW5lciApID09PSAtIDEgKSB7XG5cblx0XHRcdGxpc3RlbmVyc1sgdHlwZSBdLnB1c2goIGxpc3RlbmVyICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRoYXNFdmVudExpc3RlbmVyOiBmdW5jdGlvbiAoIHR5cGUsIGxpc3RlbmVyICkge1xuXG5cdFx0aWYgKCB0aGlzLl9saXN0ZW5lcnMgPT09IHVuZGVmaW5lZCApIHJldHVybiBmYWxzZTtcblxuXHRcdHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG5cblx0XHRyZXR1cm4gbGlzdGVuZXJzWyB0eXBlIF0gIT09IHVuZGVmaW5lZCAmJiBsaXN0ZW5lcnNbIHR5cGUgXS5pbmRleE9mKCBsaXN0ZW5lciApICE9PSAtIDE7XG5cblx0fSxcblxuXHRyZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbiAoIHR5cGUsIGxpc3RlbmVyICkge1xuXG5cdFx0aWYgKCB0aGlzLl9saXN0ZW5lcnMgPT09IHVuZGVmaW5lZCApIHJldHVybjtcblxuXHRcdHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG5cdFx0dmFyIGxpc3RlbmVyQXJyYXkgPSBsaXN0ZW5lcnNbIHR5cGUgXTtcblxuXHRcdGlmICggbGlzdGVuZXJBcnJheSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgaW5kZXggPSBsaXN0ZW5lckFycmF5LmluZGV4T2YoIGxpc3RlbmVyICk7XG5cblx0XHRcdGlmICggaW5kZXggIT09IC0gMSApIHtcblxuXHRcdFx0XHRsaXN0ZW5lckFycmF5LnNwbGljZSggaW5kZXgsIDEgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0ZGlzcGF0Y2hFdmVudDogZnVuY3Rpb24gKCBldmVudCApIHtcblxuXHRcdGlmICggdGhpcy5fbGlzdGVuZXJzID09PSB1bmRlZmluZWQgKSByZXR1cm47XG5cblx0XHR2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzO1xuXHRcdHZhciBsaXN0ZW5lckFycmF5ID0gbGlzdGVuZXJzWyBldmVudC50eXBlIF07XG5cblx0XHRpZiAoIGxpc3RlbmVyQXJyYXkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gdGhpcztcblxuXHRcdFx0dmFyIGFycmF5ID0gW10sIGkgPSAwO1xuXHRcdFx0dmFyIGxlbmd0aCA9IGxpc3RlbmVyQXJyYXkubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHRhcnJheVsgaSBdID0gbGlzdGVuZXJBcnJheVsgaSBdO1xuXG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdGFycmF5WyBpIF0uY2FsbCggdGhpcywgZXZlbnQgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG52YXIgUkVWSVNJT04gPSAnODUnO1xudmFyIE1PVVNFID0geyBMRUZUOiAwLCBNSURETEU6IDEsIFJJR0hUOiAyIH07XG52YXIgQ3VsbEZhY2VOb25lID0gMDtcbnZhciBDdWxsRmFjZUJhY2sgPSAxO1xudmFyIEN1bGxGYWNlRnJvbnQgPSAyO1xudmFyIEN1bGxGYWNlRnJvbnRCYWNrID0gMztcbnZhciBGcm9udEZhY2VEaXJlY3Rpb25DVyA9IDA7XG52YXIgRnJvbnRGYWNlRGlyZWN0aW9uQ0NXID0gMTtcbnZhciBCYXNpY1NoYWRvd01hcCA9IDA7XG52YXIgUENGU2hhZG93TWFwID0gMTtcbnZhciBQQ0ZTb2Z0U2hhZG93TWFwID0gMjtcbnZhciBGcm9udFNpZGUgPSAwO1xudmFyIEJhY2tTaWRlID0gMTtcbnZhciBEb3VibGVTaWRlID0gMjtcbnZhciBGbGF0U2hhZGluZyA9IDE7XG52YXIgU21vb3RoU2hhZGluZyA9IDI7XG52YXIgTm9Db2xvcnMgPSAwO1xudmFyIEZhY2VDb2xvcnMgPSAxO1xudmFyIFZlcnRleENvbG9ycyA9IDI7XG52YXIgTm9CbGVuZGluZyA9IDA7XG52YXIgTm9ybWFsQmxlbmRpbmcgPSAxO1xudmFyIEFkZGl0aXZlQmxlbmRpbmcgPSAyO1xudmFyIFN1YnRyYWN0aXZlQmxlbmRpbmcgPSAzO1xudmFyIE11bHRpcGx5QmxlbmRpbmcgPSA0O1xudmFyIEN1c3RvbUJsZW5kaW5nID0gNTtcbnZhciBBZGRFcXVhdGlvbiA9IDEwMDtcbnZhciBTdWJ0cmFjdEVxdWF0aW9uID0gMTAxO1xudmFyIFJldmVyc2VTdWJ0cmFjdEVxdWF0aW9uID0gMTAyO1xudmFyIE1pbkVxdWF0aW9uID0gMTAzO1xudmFyIE1heEVxdWF0aW9uID0gMTA0O1xudmFyIFplcm9GYWN0b3IgPSAyMDA7XG52YXIgT25lRmFjdG9yID0gMjAxO1xudmFyIFNyY0NvbG9yRmFjdG9yID0gMjAyO1xudmFyIE9uZU1pbnVzU3JjQ29sb3JGYWN0b3IgPSAyMDM7XG52YXIgU3JjQWxwaGFGYWN0b3IgPSAyMDQ7XG52YXIgT25lTWludXNTcmNBbHBoYUZhY3RvciA9IDIwNTtcbnZhciBEc3RBbHBoYUZhY3RvciA9IDIwNjtcbnZhciBPbmVNaW51c0RzdEFscGhhRmFjdG9yID0gMjA3O1xudmFyIERzdENvbG9yRmFjdG9yID0gMjA4O1xudmFyIE9uZU1pbnVzRHN0Q29sb3JGYWN0b3IgPSAyMDk7XG52YXIgU3JjQWxwaGFTYXR1cmF0ZUZhY3RvciA9IDIxMDtcbnZhciBOZXZlckRlcHRoID0gMDtcbnZhciBBbHdheXNEZXB0aCA9IDE7XG52YXIgTGVzc0RlcHRoID0gMjtcbnZhciBMZXNzRXF1YWxEZXB0aCA9IDM7XG52YXIgRXF1YWxEZXB0aCA9IDQ7XG52YXIgR3JlYXRlckVxdWFsRGVwdGggPSA1O1xudmFyIEdyZWF0ZXJEZXB0aCA9IDY7XG52YXIgTm90RXF1YWxEZXB0aCA9IDc7XG52YXIgTXVsdGlwbHlPcGVyYXRpb24gPSAwO1xudmFyIE1peE9wZXJhdGlvbiA9IDE7XG52YXIgQWRkT3BlcmF0aW9uID0gMjtcbnZhciBOb1RvbmVNYXBwaW5nID0gMDtcbnZhciBMaW5lYXJUb25lTWFwcGluZyA9IDE7XG52YXIgUmVpbmhhcmRUb25lTWFwcGluZyA9IDI7XG52YXIgVW5jaGFydGVkMlRvbmVNYXBwaW5nID0gMztcbnZhciBDaW5lb25Ub25lTWFwcGluZyA9IDQ7XG52YXIgVVZNYXBwaW5nID0gMzAwO1xudmFyIEN1YmVSZWZsZWN0aW9uTWFwcGluZyA9IDMwMTtcbnZhciBDdWJlUmVmcmFjdGlvbk1hcHBpbmcgPSAzMDI7XG52YXIgRXF1aXJlY3Rhbmd1bGFyUmVmbGVjdGlvbk1hcHBpbmcgPSAzMDM7XG52YXIgRXF1aXJlY3Rhbmd1bGFyUmVmcmFjdGlvbk1hcHBpbmcgPSAzMDQ7XG52YXIgU3BoZXJpY2FsUmVmbGVjdGlvbk1hcHBpbmcgPSAzMDU7XG52YXIgQ3ViZVVWUmVmbGVjdGlvbk1hcHBpbmcgPSAzMDY7XG52YXIgQ3ViZVVWUmVmcmFjdGlvbk1hcHBpbmcgPSAzMDc7XG52YXIgUmVwZWF0V3JhcHBpbmcgPSAxMDAwO1xudmFyIENsYW1wVG9FZGdlV3JhcHBpbmcgPSAxMDAxO1xudmFyIE1pcnJvcmVkUmVwZWF0V3JhcHBpbmcgPSAxMDAyO1xudmFyIE5lYXJlc3RGaWx0ZXIgPSAxMDAzO1xudmFyIE5lYXJlc3RNaXBNYXBOZWFyZXN0RmlsdGVyID0gMTAwNDtcbnZhciBOZWFyZXN0TWlwTWFwTGluZWFyRmlsdGVyID0gMTAwNTtcbnZhciBMaW5lYXJGaWx0ZXIgPSAxMDA2O1xudmFyIExpbmVhck1pcE1hcE5lYXJlc3RGaWx0ZXIgPSAxMDA3O1xudmFyIExpbmVhck1pcE1hcExpbmVhckZpbHRlciA9IDEwMDg7XG52YXIgVW5zaWduZWRCeXRlVHlwZSA9IDEwMDk7XG52YXIgQnl0ZVR5cGUgPSAxMDEwO1xudmFyIFNob3J0VHlwZSA9IDEwMTE7XG52YXIgVW5zaWduZWRTaG9ydFR5cGUgPSAxMDEyO1xudmFyIEludFR5cGUgPSAxMDEzO1xudmFyIFVuc2lnbmVkSW50VHlwZSA9IDEwMTQ7XG52YXIgRmxvYXRUeXBlID0gMTAxNTtcbnZhciBIYWxmRmxvYXRUeXBlID0gMTAxNjtcbnZhciBVbnNpZ25lZFNob3J0NDQ0NFR5cGUgPSAxMDE3O1xudmFyIFVuc2lnbmVkU2hvcnQ1NTUxVHlwZSA9IDEwMTg7XG52YXIgVW5zaWduZWRTaG9ydDU2NVR5cGUgPSAxMDE5O1xudmFyIFVuc2lnbmVkSW50MjQ4VHlwZSA9IDEwMjA7XG52YXIgQWxwaGFGb3JtYXQgPSAxMDIxO1xudmFyIFJHQkZvcm1hdCA9IDEwMjI7XG52YXIgUkdCQUZvcm1hdCA9IDEwMjM7XG52YXIgTHVtaW5hbmNlRm9ybWF0ID0gMTAyNDtcbnZhciBMdW1pbmFuY2VBbHBoYUZvcm1hdCA9IDEwMjU7XG52YXIgUkdCRUZvcm1hdCA9IFJHQkFGb3JtYXQ7XG52YXIgRGVwdGhGb3JtYXQgPSAxMDI2O1xudmFyIERlcHRoU3RlbmNpbEZvcm1hdCA9IDEwMjc7XG52YXIgUkdCX1MzVENfRFhUMV9Gb3JtYXQgPSAyMDAxO1xudmFyIFJHQkFfUzNUQ19EWFQxX0Zvcm1hdCA9IDIwMDI7XG52YXIgUkdCQV9TM1RDX0RYVDNfRm9ybWF0ID0gMjAwMztcbnZhciBSR0JBX1MzVENfRFhUNV9Gb3JtYXQgPSAyMDA0O1xudmFyIFJHQl9QVlJUQ180QlBQVjFfRm9ybWF0ID0gMjEwMDtcbnZhciBSR0JfUFZSVENfMkJQUFYxX0Zvcm1hdCA9IDIxMDE7XG52YXIgUkdCQV9QVlJUQ180QlBQVjFfRm9ybWF0ID0gMjEwMjtcbnZhciBSR0JBX1BWUlRDXzJCUFBWMV9Gb3JtYXQgPSAyMTAzO1xudmFyIFJHQl9FVEMxX0Zvcm1hdCA9IDIxNTE7XG52YXIgTG9vcE9uY2UgPSAyMjAwO1xudmFyIExvb3BSZXBlYXQgPSAyMjAxO1xudmFyIExvb3BQaW5nUG9uZyA9IDIyMDI7XG52YXIgSW50ZXJwb2xhdGVEaXNjcmV0ZSA9IDIzMDA7XG52YXIgSW50ZXJwb2xhdGVMaW5lYXIgPSAyMzAxO1xudmFyIEludGVycG9sYXRlU21vb3RoID0gMjMwMjtcbnZhciBaZXJvQ3VydmF0dXJlRW5kaW5nID0gMjQwMDtcbnZhciBaZXJvU2xvcGVFbmRpbmcgPSAyNDAxO1xudmFyIFdyYXBBcm91bmRFbmRpbmcgPSAyNDAyO1xudmFyIFRyaWFuZ2xlc0RyYXdNb2RlID0gMDtcbnZhciBUcmlhbmdsZVN0cmlwRHJhd01vZGUgPSAxO1xudmFyIFRyaWFuZ2xlRmFuRHJhd01vZGUgPSAyO1xudmFyIExpbmVhckVuY29kaW5nID0gMzAwMDtcbnZhciBzUkdCRW5jb2RpbmcgPSAzMDAxO1xudmFyIEdhbW1hRW5jb2RpbmcgPSAzMDA3O1xudmFyIFJHQkVFbmNvZGluZyA9IDMwMDI7XG52YXIgTG9nTHV2RW5jb2RpbmcgPSAzMDAzO1xudmFyIFJHQk03RW5jb2RpbmcgPSAzMDA0O1xudmFyIFJHQk0xNkVuY29kaW5nID0gMzAwNTtcbnZhciBSR0JERW5jb2RpbmcgPSAzMDA2O1xudmFyIEJhc2ljRGVwdGhQYWNraW5nID0gMzIwMDtcbnZhciBSR0JBRGVwdGhQYWNraW5nID0gMzIwMTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG52YXIgX01hdGggPSB7XG5cblx0REVHMlJBRDogTWF0aC5QSSAvIDE4MCxcblx0UkFEMkRFRzogMTgwIC8gTWF0aC5QSSxcblxuXHRnZW5lcmF0ZVVVSUQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIGh0dHA6Ly93d3cuYnJvb2ZhLmNvbS9Ub29scy9NYXRoLnV1aWQuaHRtXG5cblx0XHR2YXIgY2hhcnMgPSAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonLnNwbGl0KCAnJyApO1xuXHRcdHZhciB1dWlkID0gbmV3IEFycmF5KCAzNiApO1xuXHRcdHZhciBybmQgPSAwLCByO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGdlbmVyYXRlVVVJRCgpIHtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgMzY7IGkgKysgKSB7XG5cblx0XHRcdFx0aWYgKCBpID09PSA4IHx8IGkgPT09IDEzIHx8IGkgPT09IDE4IHx8IGkgPT09IDIzICkge1xuXG5cdFx0XHRcdFx0dXVpZFsgaSBdID0gJy0nO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGkgPT09IDE0ICkge1xuXG5cdFx0XHRcdFx0dXVpZFsgaSBdID0gJzQnO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRpZiAoIHJuZCA8PSAweDAyICkgcm5kID0gMHgyMDAwMDAwICsgKCBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwICkgfCAwO1xuXHRcdFx0XHRcdHIgPSBybmQgJiAweGY7XG5cdFx0XHRcdFx0cm5kID0gcm5kID4+IDQ7XG5cdFx0XHRcdFx0dXVpZFsgaSBdID0gY2hhcnNbICggaSA9PT0gMTkgKSA/ICggciAmIDB4MyApIHwgMHg4IDogciBdO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdXVpZC5qb2luKCAnJyApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Y2xhbXA6IGZ1bmN0aW9uICggdmFsdWUsIG1pbiwgbWF4ICkge1xuXG5cdFx0cmV0dXJuIE1hdGgubWF4KCBtaW4sIE1hdGgubWluKCBtYXgsIHZhbHVlICkgKTtcblxuXHR9LFxuXG5cdC8vIGNvbXB1dGUgZXVjbGlkaWFuIG1vZHVsbyBvZiBtICUgblxuXHQvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Nb2R1bG9fb3BlcmF0aW9uXG5cblx0ZXVjbGlkZWFuTW9kdWxvOiBmdW5jdGlvbiAoIG4sIG0gKSB7XG5cblx0XHRyZXR1cm4gKCAoIG4gJSBtICkgKyBtICkgJSBtO1xuXG5cdH0sXG5cblx0Ly8gTGluZWFyIG1hcHBpbmcgZnJvbSByYW5nZSA8YTEsIGEyPiB0byByYW5nZSA8YjEsIGIyPlxuXG5cdG1hcExpbmVhcjogZnVuY3Rpb24gKCB4LCBhMSwgYTIsIGIxLCBiMiApIHtcblxuXHRcdHJldHVybiBiMSArICggeCAtIGExICkgKiAoIGIyIC0gYjEgKSAvICggYTIgLSBhMSApO1xuXG5cdH0sXG5cblx0Ly8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGluZWFyX2ludGVycG9sYXRpb25cblxuXHRsZXJwOiBmdW5jdGlvbiAoIHgsIHksIHQgKSB7XG5cblx0XHRyZXR1cm4gKCAxIC0gdCApICogeCArIHQgKiB5O1xuXG5cdH0sXG5cblx0Ly8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TbW9vdGhzdGVwXG5cblx0c21vb3Roc3RlcDogZnVuY3Rpb24gKCB4LCBtaW4sIG1heCApIHtcblxuXHRcdGlmICggeCA8PSBtaW4gKSByZXR1cm4gMDtcblx0XHRpZiAoIHggPj0gbWF4ICkgcmV0dXJuIDE7XG5cblx0XHR4ID0gKCB4IC0gbWluICkgLyAoIG1heCAtIG1pbiApO1xuXG5cdFx0cmV0dXJuIHggKiB4ICogKCAzIC0gMiAqIHggKTtcblxuXHR9LFxuXG5cdHNtb290aGVyc3RlcDogZnVuY3Rpb24gKCB4LCBtaW4sIG1heCApIHtcblxuXHRcdGlmICggeCA8PSBtaW4gKSByZXR1cm4gMDtcblx0XHRpZiAoIHggPj0gbWF4ICkgcmV0dXJuIDE7XG5cblx0XHR4ID0gKCB4IC0gbWluICkgLyAoIG1heCAtIG1pbiApO1xuXG5cdFx0cmV0dXJuIHggKiB4ICogeCAqICggeCAqICggeCAqIDYgLSAxNSApICsgMTAgKTtcblxuXHR9LFxuXG5cdC8vIFJhbmRvbSBpbnRlZ2VyIGZyb20gPGxvdywgaGlnaD4gaW50ZXJ2YWxcblxuXHRyYW5kSW50OiBmdW5jdGlvbiAoIGxvdywgaGlnaCApIHtcblxuXHRcdHJldHVybiBsb3cgKyBNYXRoLmZsb29yKCBNYXRoLnJhbmRvbSgpICogKCBoaWdoIC0gbG93ICsgMSApICk7XG5cblx0fSxcblxuXHQvLyBSYW5kb20gZmxvYXQgZnJvbSA8bG93LCBoaWdoPiBpbnRlcnZhbFxuXG5cdHJhbmRGbG9hdDogZnVuY3Rpb24gKCBsb3csIGhpZ2ggKSB7XG5cblx0XHRyZXR1cm4gbG93ICsgTWF0aC5yYW5kb20oKSAqICggaGlnaCAtIGxvdyApO1xuXG5cdH0sXG5cblx0Ly8gUmFuZG9tIGZsb2F0IGZyb20gPC1yYW5nZS8yLCByYW5nZS8yPiBpbnRlcnZhbFxuXG5cdHJhbmRGbG9hdFNwcmVhZDogZnVuY3Rpb24gKCByYW5nZSApIHtcblxuXHRcdHJldHVybiByYW5nZSAqICggMC41IC0gTWF0aC5yYW5kb20oKSApO1xuXG5cdH0sXG5cblx0ZGVnVG9SYWQ6IGZ1bmN0aW9uICggZGVncmVlcyApIHtcblxuXHRcdHJldHVybiBkZWdyZWVzICogX01hdGguREVHMlJBRDtcblxuXHR9LFxuXG5cdHJhZFRvRGVnOiBmdW5jdGlvbiAoIHJhZGlhbnMgKSB7XG5cblx0XHRyZXR1cm4gcmFkaWFucyAqIF9NYXRoLlJBRDJERUc7XG5cblx0fSxcblxuXHRpc1Bvd2VyT2ZUd286IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRyZXR1cm4gKCB2YWx1ZSAmICggdmFsdWUgLSAxICkgKSA9PT0gMCAmJiB2YWx1ZSAhPT0gMDtcblxuXHR9LFxuXG5cdG5lYXJlc3RQb3dlck9mVHdvOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0cmV0dXJuIE1hdGgucG93KCAyLCBNYXRoLnJvdW5kKCBNYXRoLmxvZyggdmFsdWUgKSAvIE1hdGguTE4yICkgKTtcblxuXHR9LFxuXG5cdG5leHRQb3dlck9mVHdvOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dmFsdWUgLS07XG5cdFx0dmFsdWUgfD0gdmFsdWUgPj4gMTtcblx0XHR2YWx1ZSB8PSB2YWx1ZSA+PiAyO1xuXHRcdHZhbHVlIHw9IHZhbHVlID4+IDQ7XG5cdFx0dmFsdWUgfD0gdmFsdWUgPj4gODtcblx0XHR2YWx1ZSB8PSB2YWx1ZSA+PiAxNjtcblx0XHR2YWx1ZSArKztcblxuXHRcdHJldHVybiB2YWx1ZTtcblxuXHR9XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgcGhpbG9nYiAvIGh0dHA6Ly9ibG9nLnRoZWppdC5vcmcvXG4gKiBAYXV0aG9yIGVncmFldGhlciAvIGh0dHA6Ly9lZ3JhZXRoZXIuY29tL1xuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICovXG5cbmZ1bmN0aW9uIFZlY3RvcjIoIHgsIHkgKSB7XG5cblx0dGhpcy54ID0geCB8fCAwO1xuXHR0aGlzLnkgPSB5IHx8IDA7XG5cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIFZlY3RvcjIucHJvdG90eXBlLCB7XG5cblx0XCJ3aWR0aFwiIDoge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLng7XG5cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHR0aGlzLnggPSB2YWx1ZTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdFwiaGVpZ2h0XCIgOiB7XG5cblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMueTtcblxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdHRoaXMueSA9IHZhbHVlO1xuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG5PYmplY3QuYXNzaWduKCBWZWN0b3IyLnByb3RvdHlwZSwge1xuXG5cdGlzVmVjdG9yMjogdHJ1ZSxcblxuXHRzZXQ6IGZ1bmN0aW9uICggeCwgeSApIHtcblxuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHRoaXMueCA9IHNjYWxhcjtcblx0XHR0aGlzLnkgPSBzY2FsYXI7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFg6IGZ1bmN0aW9uICggeCApIHtcblxuXHRcdHRoaXMueCA9IHg7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFk6IGZ1bmN0aW9uICggeSApIHtcblxuXHRcdHRoaXMueSA9IHk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldENvbXBvbmVudDogZnVuY3Rpb24gKCBpbmRleCwgdmFsdWUgKSB7XG5cblx0XHRzd2l0Y2ggKCBpbmRleCApIHtcblxuXHRcdFx0Y2FzZSAwOiB0aGlzLnggPSB2YWx1ZTsgYnJlYWs7XG5cdFx0XHRjYXNlIDE6IHRoaXMueSA9IHZhbHVlOyBicmVhaztcblx0XHRcdGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvciggJ2luZGV4IGlzIG91dCBvZiByYW5nZTogJyArIGluZGV4ICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldENvbXBvbmVudDogZnVuY3Rpb24gKCBpbmRleCApIHtcblxuXHRcdHN3aXRjaCAoIGluZGV4ICkge1xuXG5cdFx0XHRjYXNlIDA6IHJldHVybiB0aGlzLng7XG5cdFx0XHRjYXNlIDE6IHJldHVybiB0aGlzLnk7XG5cdFx0XHRkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoICdpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICcgKyBpbmRleCApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvciggdGhpcy54LCB0aGlzLnkgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHRoaXMueCA9IHYueDtcblx0XHR0aGlzLnkgPSB2Lnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjI6IC5hZGQoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5hZGRWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggKz0gdi54O1xuXHRcdHRoaXMueSArPSB2Lnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZFNjYWxhcjogZnVuY3Rpb24gKCBzICkge1xuXG5cdFx0dGhpcy54ICs9IHM7XG5cdFx0dGhpcy55ICs9IHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZFZlY3RvcnM6IGZ1bmN0aW9uICggYSwgYiApIHtcblxuXHRcdHRoaXMueCA9IGEueCArIGIueDtcblx0XHR0aGlzLnkgPSBhLnkgKyBiLnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZFNjYWxlZFZlY3RvcjogZnVuY3Rpb24gKCB2LCBzICkge1xuXG5cdFx0dGhpcy54ICs9IHYueCAqIHM7XG5cdFx0dGhpcy55ICs9IHYueSAqIHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHN1YjogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjI6IC5zdWIoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5zdWJWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5zdWJWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggLT0gdi54O1xuXHRcdHRoaXMueSAtPSB2Lnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHN1YlNjYWxhcjogZnVuY3Rpb24gKCBzICkge1xuXG5cdFx0dGhpcy54IC09IHM7XG5cdFx0dGhpcy55IC09IHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHN1YlZlY3RvcnM6IGZ1bmN0aW9uICggYSwgYiApIHtcblxuXHRcdHRoaXMueCA9IGEueCAtIGIueDtcblx0XHR0aGlzLnkgPSBhLnkgLSBiLnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG11bHRpcGx5OiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggKj0gdi54O1xuXHRcdHRoaXMueSAqPSB2Lnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG11bHRpcGx5U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHRoaXMueCAqPSBzY2FsYXI7XG5cdFx0dGhpcy55ICo9IHNjYWxhcjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGl2aWRlOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggLz0gdi54O1xuXHRcdHRoaXMueSAvPSB2Lnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGRpdmlkZVNjYWxhcjogZnVuY3Rpb24gKCBzY2FsYXIgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVNjYWxhciggMSAvIHNjYWxhciApO1xuXG5cdH0sXG5cblx0bWluOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1pbiggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1pbiggdGhpcy55LCB2LnkgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWF4OiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1heCggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1heCggdGhpcy55LCB2LnkgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xhbXA6IGZ1bmN0aW9uICggbWluLCBtYXggKSB7XG5cblx0XHQvLyBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgbWluIDwgbWF4LCBpZiB0aGlzIGFzc3VtcHRpb24gaXNuJ3QgdHJ1ZSBpdCB3aWxsIG5vdCBvcGVyYXRlIGNvcnJlY3RseVxuXG5cdFx0dGhpcy54ID0gTWF0aC5tYXgoIG1pbi54LCBNYXRoLm1pbiggbWF4LngsIHRoaXMueCApICk7XG5cdFx0dGhpcy55ID0gTWF0aC5tYXgoIG1pbi55LCBNYXRoLm1pbiggbWF4LnksIHRoaXMueSApICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsYW1wU2NhbGFyOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbWluID0gbmV3IFZlY3RvcjIoKTtcblx0XHR2YXIgbWF4ID0gbmV3IFZlY3RvcjIoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBjbGFtcFNjYWxhciggbWluVmFsLCBtYXhWYWwgKSB7XG5cblx0XHRcdG1pbi5zZXQoIG1pblZhbCwgbWluVmFsICk7XG5cdFx0XHRtYXguc2V0KCBtYXhWYWwsIG1heFZhbCApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5jbGFtcCggbWluLCBtYXggKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGNsYW1wTGVuZ3RoOiBmdW5jdGlvbiAoIG1pbiwgbWF4ICkge1xuXG5cdFx0dmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVNjYWxhciggTWF0aC5tYXgoIG1pbiwgTWF0aC5taW4oIG1heCwgbGVuZ3RoICkgKSAvIGxlbmd0aCApO1xuXG5cdH0sXG5cblx0Zmxvb3I6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9IE1hdGguZmxvb3IoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9IE1hdGguZmxvb3IoIHRoaXMueSApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjZWlsOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLmNlaWwoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9IE1hdGguY2VpbCggdGhpcy55ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHJvdW5kOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLnJvdW5kKCB0aGlzLnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLnJvdW5kKCB0aGlzLnkgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0cm91bmRUb1plcm86IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9ICggdGhpcy54IDwgMCApID8gTWF0aC5jZWlsKCB0aGlzLnggKSA6IE1hdGguZmxvb3IoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9ICggdGhpcy55IDwgMCApID8gTWF0aC5jZWlsKCB0aGlzLnkgKSA6IE1hdGguZmxvb3IoIHRoaXMueSApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRuZWdhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9IC0gdGhpcy54O1xuXHRcdHRoaXMueSA9IC0gdGhpcy55O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRkb3Q6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHJldHVybiB0aGlzLnggKiB2LnggKyB0aGlzLnkgKiB2Lnk7XG5cblx0fSxcblxuXHRsZW5ndGhTcTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueTtcblxuXHR9LFxuXG5cdGxlbmd0aDogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIE1hdGguc3FydCggdGhpcy54ICogdGhpcy54ICsgdGhpcy55ICogdGhpcy55ICk7XG5cblx0fSxcblxuXHRsZW5ndGhNYW5oYXR0YW46IGZ1bmN0aW9uKCkge1xuXG5cdFx0cmV0dXJuIE1hdGguYWJzKCB0aGlzLnggKSArIE1hdGguYWJzKCB0aGlzLnkgKTtcblxuXHR9LFxuXG5cdG5vcm1hbGl6ZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZGl2aWRlU2NhbGFyKCB0aGlzLmxlbmd0aCgpICk7XG5cblx0fSxcblxuXHRhbmdsZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gY29tcHV0ZXMgdGhlIGFuZ2xlIGluIHJhZGlhbnMgd2l0aCByZXNwZWN0IHRvIHRoZSBwb3NpdGl2ZSB4LWF4aXNcblxuXHRcdHZhciBhbmdsZSA9IE1hdGguYXRhbjIoIHRoaXMueSwgdGhpcy54ICk7XG5cblx0XHRpZiAoIGFuZ2xlIDwgMCApIGFuZ2xlICs9IDIgKiBNYXRoLlBJO1xuXG5cdFx0cmV0dXJuIGFuZ2xlO1xuXG5cdH0sXG5cblx0ZGlzdGFuY2VUbzogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0cmV0dXJuIE1hdGguc3FydCggdGhpcy5kaXN0YW5jZVRvU3F1YXJlZCggdiApICk7XG5cblx0fSxcblxuXHRkaXN0YW5jZVRvU3F1YXJlZDogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0dmFyIGR4ID0gdGhpcy54IC0gdi54LCBkeSA9IHRoaXMueSAtIHYueTtcblx0XHRyZXR1cm4gZHggKiBkeCArIGR5ICogZHk7XG5cblx0fSxcblxuXHRkaXN0YW5jZVRvTWFuaGF0dGFuOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHRyZXR1cm4gTWF0aC5hYnMoIHRoaXMueCAtIHYueCApICsgTWF0aC5hYnMoIHRoaXMueSAtIHYueSApO1xuXG5cdH0sXG5cblx0c2V0TGVuZ3RoOiBmdW5jdGlvbiAoIGxlbmd0aCApIHtcblxuXHRcdHJldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKCBsZW5ndGggLyB0aGlzLmxlbmd0aCgpICk7XG5cblx0fSxcblxuXHRsZXJwOiBmdW5jdGlvbiAoIHYsIGFscGhhICkge1xuXG5cdFx0dGhpcy54ICs9ICggdi54IC0gdGhpcy54ICkgKiBhbHBoYTtcblx0XHR0aGlzLnkgKz0gKCB2LnkgLSB0aGlzLnkgKSAqIGFscGhhO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRsZXJwVmVjdG9yczogZnVuY3Rpb24gKCB2MSwgdjIsIGFscGhhICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuc3ViVmVjdG9ycyggdjIsIHYxICkubXVsdGlwbHlTY2FsYXIoIGFscGhhICkuYWRkKCB2MSApO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHRyZXR1cm4gKCAoIHYueCA9PT0gdGhpcy54ICkgJiYgKCB2LnkgPT09IHRoaXMueSApICk7XG5cblx0fSxcblxuXHRmcm9tQXJyYXk6IGZ1bmN0aW9uICggYXJyYXksIG9mZnNldCApIHtcblxuXHRcdGlmICggb2Zmc2V0ID09PSB1bmRlZmluZWQgKSBvZmZzZXQgPSAwO1xuXG5cdFx0dGhpcy54ID0gYXJyYXlbIG9mZnNldCBdO1xuXHRcdHRoaXMueSA9IGFycmF5WyBvZmZzZXQgKyAxIF07XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uICggYXJyYXksIG9mZnNldCApIHtcblxuXHRcdGlmICggYXJyYXkgPT09IHVuZGVmaW5lZCApIGFycmF5ID0gW107XG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIG9mZnNldCA9IDA7XG5cblx0XHRhcnJheVsgb2Zmc2V0IF0gPSB0aGlzLng7XG5cdFx0YXJyYXlbIG9mZnNldCArIDEgXSA9IHRoaXMueTtcblxuXHRcdHJldHVybiBhcnJheTtcblxuXHR9LFxuXG5cdGZyb21CdWZmZXJBdHRyaWJ1dGU6IGZ1bmN0aW9uICggYXR0cmlidXRlLCBpbmRleCwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBvZmZzZXQgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVmVjdG9yMjogb2Zmc2V0IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSAuZnJvbUJ1ZmZlckF0dHJpYnV0ZSgpLicgKTtcblxuXHRcdH1cblxuXHRcdHRoaXMueCA9IGF0dHJpYnV0ZS5nZXRYKCBpbmRleCApO1xuXHRcdHRoaXMueSA9IGF0dHJpYnV0ZS5nZXRZKCBpbmRleCApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRyb3RhdGVBcm91bmQ6IGZ1bmN0aW9uICggY2VudGVyLCBhbmdsZSApIHtcblxuXHRcdHZhciBjID0gTWF0aC5jb3MoIGFuZ2xlICksIHMgPSBNYXRoLnNpbiggYW5nbGUgKTtcblxuXHRcdHZhciB4ID0gdGhpcy54IC0gY2VudGVyLng7XG5cdFx0dmFyIHkgPSB0aGlzLnkgLSBjZW50ZXIueTtcblxuXHRcdHRoaXMueCA9IHggKiBjIC0geSAqIHMgKyBjZW50ZXIueDtcblx0XHR0aGlzLnkgPSB4ICogcyArIHkgKiBjICsgY2VudGVyLnk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3Igc3ppbWVrIC8gaHR0cHM6Ly9naXRodWIuY29tL3N6aW1lay9cbiAqL1xuXG52YXIgdGV4dHVyZUlkID0gMDtcblxuZnVuY3Rpb24gVGV4dHVyZSggaW1hZ2UsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSwgZW5jb2RpbmcgKSB7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCAnaWQnLCB7IHZhbHVlOiB0ZXh0dXJlSWQgKysgfSApO1xuXG5cdHRoaXMudXVpZCA9IF9NYXRoLmdlbmVyYXRlVVVJRCgpO1xuXG5cdHRoaXMubmFtZSA9ICcnO1xuXG5cdHRoaXMuaW1hZ2UgPSBpbWFnZSAhPT0gdW5kZWZpbmVkID8gaW1hZ2UgOiBUZXh0dXJlLkRFRkFVTFRfSU1BR0U7XG5cdHRoaXMubWlwbWFwcyA9IFtdO1xuXG5cdHRoaXMubWFwcGluZyA9IG1hcHBpbmcgIT09IHVuZGVmaW5lZCA/IG1hcHBpbmcgOiBUZXh0dXJlLkRFRkFVTFRfTUFQUElORztcblxuXHR0aGlzLndyYXBTID0gd3JhcFMgIT09IHVuZGVmaW5lZCA/IHdyYXBTIDogQ2xhbXBUb0VkZ2VXcmFwcGluZztcblx0dGhpcy53cmFwVCA9IHdyYXBUICE9PSB1bmRlZmluZWQgPyB3cmFwVCA6IENsYW1wVG9FZGdlV3JhcHBpbmc7XG5cblx0dGhpcy5tYWdGaWx0ZXIgPSBtYWdGaWx0ZXIgIT09IHVuZGVmaW5lZCA/IG1hZ0ZpbHRlciA6IExpbmVhckZpbHRlcjtcblx0dGhpcy5taW5GaWx0ZXIgPSBtaW5GaWx0ZXIgIT09IHVuZGVmaW5lZCA/IG1pbkZpbHRlciA6IExpbmVhck1pcE1hcExpbmVhckZpbHRlcjtcblxuXHR0aGlzLmFuaXNvdHJvcHkgPSBhbmlzb3Ryb3B5ICE9PSB1bmRlZmluZWQgPyBhbmlzb3Ryb3B5IDogMTtcblxuXHR0aGlzLmZvcm1hdCA9IGZvcm1hdCAhPT0gdW5kZWZpbmVkID8gZm9ybWF0IDogUkdCQUZvcm1hdDtcblx0dGhpcy50eXBlID0gdHlwZSAhPT0gdW5kZWZpbmVkID8gdHlwZSA6IFVuc2lnbmVkQnl0ZVR5cGU7XG5cblx0dGhpcy5vZmZzZXQgPSBuZXcgVmVjdG9yMiggMCwgMCApO1xuXHR0aGlzLnJlcGVhdCA9IG5ldyBWZWN0b3IyKCAxLCAxICk7XG5cblx0dGhpcy5nZW5lcmF0ZU1pcG1hcHMgPSB0cnVlO1xuXHR0aGlzLnByZW11bHRpcGx5QWxwaGEgPSBmYWxzZTtcblx0dGhpcy5mbGlwWSA9IHRydWU7XG5cdHRoaXMudW5wYWNrQWxpZ25tZW50ID0gNDtcdC8vIHZhbGlkIHZhbHVlczogMSwgMiwgNCwgOCAoc2VlIGh0dHA6Ly93d3cua2hyb25vcy5vcmcvb3BlbmdsZXMvc2RrL2RvY3MvbWFuL3hodG1sL2dsUGl4ZWxTdG9yZWkueG1sKVxuXG5cdC8vIFZhbHVlcyBvZiBlbmNvZGluZyAhPT0gVEhSRUUuTGluZWFyRW5jb2Rpbmcgb25seSBzdXBwb3J0ZWQgb24gbWFwLCBlbnZNYXAgYW5kIGVtaXNzaXZlTWFwLlxuXHQvL1xuXHQvLyBBbHNvIGNoYW5naW5nIHRoZSBlbmNvZGluZyBhZnRlciBhbHJlYWR5IHVzZWQgYnkgYSBNYXRlcmlhbCB3aWxsIG5vdCBhdXRvbWF0aWNhbGx5IG1ha2UgdGhlIE1hdGVyaWFsXG5cdC8vIHVwZGF0ZS4gIFlvdSBuZWVkIHRvIGV4cGxpY2l0bHkgY2FsbCBNYXRlcmlhbC5uZWVkc1VwZGF0ZSB0byB0cmlnZ2VyIGl0IHRvIHJlY29tcGlsZS5cblx0dGhpcy5lbmNvZGluZyA9IGVuY29kaW5nICE9PSB1bmRlZmluZWQgPyBlbmNvZGluZyA6IExpbmVhckVuY29kaW5nO1xuXG5cdHRoaXMudmVyc2lvbiA9IDA7XG5cdHRoaXMub25VcGRhdGUgPSBudWxsO1xuXG59XG5cblRleHR1cmUuREVGQVVMVF9JTUFHRSA9IHVuZGVmaW5lZDtcblRleHR1cmUuREVGQVVMVF9NQVBQSU5HID0gVVZNYXBwaW5nO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoIFRleHR1cmUucHJvdG90eXBlLCBcIm5lZWRzVXBkYXRlXCIsIHtcblxuXHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRpZiAoIHZhbHVlID09PSB0cnVlICkgdGhpcy52ZXJzaW9uICsrO1xuXG5cdH1cblxufSApO1xuXG5PYmplY3QuYXNzaWduKCBUZXh0dXJlLnByb3RvdHlwZSwgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZSwge1xuXG5cdGNvbnN0cnVjdG9yOiBUZXh0dXJlLFxuXG5cdGlzVGV4dHVyZTogdHJ1ZSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR0aGlzLm5hbWUgPSBzb3VyY2UubmFtZTtcblxuXHRcdHRoaXMuaW1hZ2UgPSBzb3VyY2UuaW1hZ2U7XG5cdFx0dGhpcy5taXBtYXBzID0gc291cmNlLm1pcG1hcHMuc2xpY2UoIDAgKTtcblxuXHRcdHRoaXMubWFwcGluZyA9IHNvdXJjZS5tYXBwaW5nO1xuXG5cdFx0dGhpcy53cmFwUyA9IHNvdXJjZS53cmFwUztcblx0XHR0aGlzLndyYXBUID0gc291cmNlLndyYXBUO1xuXG5cdFx0dGhpcy5tYWdGaWx0ZXIgPSBzb3VyY2UubWFnRmlsdGVyO1xuXHRcdHRoaXMubWluRmlsdGVyID0gc291cmNlLm1pbkZpbHRlcjtcblxuXHRcdHRoaXMuYW5pc290cm9weSA9IHNvdXJjZS5hbmlzb3Ryb3B5O1xuXG5cdFx0dGhpcy5mb3JtYXQgPSBzb3VyY2UuZm9ybWF0O1xuXHRcdHRoaXMudHlwZSA9IHNvdXJjZS50eXBlO1xuXG5cdFx0dGhpcy5vZmZzZXQuY29weSggc291cmNlLm9mZnNldCApO1xuXHRcdHRoaXMucmVwZWF0LmNvcHkoIHNvdXJjZS5yZXBlYXQgKTtcblxuXHRcdHRoaXMuZ2VuZXJhdGVNaXBtYXBzID0gc291cmNlLmdlbmVyYXRlTWlwbWFwcztcblx0XHR0aGlzLnByZW11bHRpcGx5QWxwaGEgPSBzb3VyY2UucHJlbXVsdGlwbHlBbHBoYTtcblx0XHR0aGlzLmZsaXBZID0gc291cmNlLmZsaXBZO1xuXHRcdHRoaXMudW5wYWNrQWxpZ25tZW50ID0gc291cmNlLnVucGFja0FsaWdubWVudDtcblx0XHR0aGlzLmVuY29kaW5nID0gc291cmNlLmVuY29kaW5nO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR0b0pTT046IGZ1bmN0aW9uICggbWV0YSApIHtcblxuXHRcdGlmICggbWV0YS50ZXh0dXJlc1sgdGhpcy51dWlkIF0gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0cmV0dXJuIG1ldGEudGV4dHVyZXNbIHRoaXMudXVpZCBdO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gZ2V0RGF0YVVSTCggaW1hZ2UgKSB7XG5cblx0XHRcdHZhciBjYW52YXM7XG5cblx0XHRcdGlmICggaW1hZ2UudG9EYXRhVVJMICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Y2FudmFzID0gaW1hZ2U7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Y2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCcsICdjYW52YXMnICk7XG5cdFx0XHRcdGNhbnZhcy53aWR0aCA9IGltYWdlLndpZHRoO1xuXHRcdFx0XHRjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuXG5cdFx0XHRcdGNhbnZhcy5nZXRDb250ZXh0KCAnMmQnICkuZHJhd0ltYWdlKCBpbWFnZSwgMCwgMCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggY2FudmFzLndpZHRoID4gMjA0OCB8fCBjYW52YXMuaGVpZ2h0ID4gMjA0OCApIHtcblxuXHRcdFx0XHRyZXR1cm4gY2FudmFzLnRvRGF0YVVSTCggJ2ltYWdlL2pwZWcnLCAwLjYgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRyZXR1cm4gY2FudmFzLnRvRGF0YVVSTCggJ2ltYWdlL3BuZycgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIG91dHB1dCA9IHtcblx0XHRcdG1ldGFkYXRhOiB7XG5cdFx0XHRcdHZlcnNpb246IDQuNSxcblx0XHRcdFx0dHlwZTogJ1RleHR1cmUnLFxuXHRcdFx0XHRnZW5lcmF0b3I6ICdUZXh0dXJlLnRvSlNPTidcblx0XHRcdH0sXG5cblx0XHRcdHV1aWQ6IHRoaXMudXVpZCxcblx0XHRcdG5hbWU6IHRoaXMubmFtZSxcblxuXHRcdFx0bWFwcGluZzogdGhpcy5tYXBwaW5nLFxuXG5cdFx0XHRyZXBlYXQ6IFsgdGhpcy5yZXBlYXQueCwgdGhpcy5yZXBlYXQueSBdLFxuXHRcdFx0b2Zmc2V0OiBbIHRoaXMub2Zmc2V0LngsIHRoaXMub2Zmc2V0LnkgXSxcblx0XHRcdHdyYXA6IFsgdGhpcy53cmFwUywgdGhpcy53cmFwVCBdLFxuXG5cdFx0XHRtaW5GaWx0ZXI6IHRoaXMubWluRmlsdGVyLFxuXHRcdFx0bWFnRmlsdGVyOiB0aGlzLm1hZ0ZpbHRlcixcblx0XHRcdGFuaXNvdHJvcHk6IHRoaXMuYW5pc290cm9weSxcblxuXHRcdFx0ZmxpcFk6IHRoaXMuZmxpcFlcblx0XHR9O1xuXG5cdFx0aWYgKCB0aGlzLmltYWdlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIFRPRE86IE1vdmUgdG8gVEhSRUUuSW1hZ2VcblxuXHRcdFx0dmFyIGltYWdlID0gdGhpcy5pbWFnZTtcblxuXHRcdFx0aWYgKCBpbWFnZS51dWlkID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0aW1hZ2UudXVpZCA9IF9NYXRoLmdlbmVyYXRlVVVJRCgpOyAvLyBVR0hcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG1ldGEuaW1hZ2VzWyBpbWFnZS51dWlkIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRtZXRhLmltYWdlc1sgaW1hZ2UudXVpZCBdID0ge1xuXHRcdFx0XHRcdHV1aWQ6IGltYWdlLnV1aWQsXG5cdFx0XHRcdFx0dXJsOiBnZXREYXRhVVJMKCBpbWFnZSApXG5cdFx0XHRcdH07XG5cblx0XHRcdH1cblxuXHRcdFx0b3V0cHV0LmltYWdlID0gaW1hZ2UudXVpZDtcblxuXHRcdH1cblxuXHRcdG1ldGEudGV4dHVyZXNbIHRoaXMudXVpZCBdID0gb3V0cHV0O1xuXG5cdFx0cmV0dXJuIG91dHB1dDtcblxuXHR9LFxuXG5cdGRpc3Bvc2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZGlzcGF0Y2hFdmVudCggeyB0eXBlOiAnZGlzcG9zZScgfSApO1xuXG5cdH0sXG5cblx0dHJhbnNmb3JtVXY6IGZ1bmN0aW9uICggdXYgKSB7XG5cblx0XHRpZiAoIHRoaXMubWFwcGluZyAhPT0gVVZNYXBwaW5nICkgcmV0dXJuO1xuXG5cdFx0dXYubXVsdGlwbHkoIHRoaXMucmVwZWF0ICk7XG5cdFx0dXYuYWRkKCB0aGlzLm9mZnNldCApO1xuXG5cdFx0aWYgKCB1di54IDwgMCB8fCB1di54ID4gMSApIHtcblxuXHRcdFx0c3dpdGNoICggdGhpcy53cmFwUyApIHtcblxuXHRcdFx0XHRjYXNlIFJlcGVhdFdyYXBwaW5nOlxuXG5cdFx0XHRcdFx0dXYueCA9IHV2LnggLSBNYXRoLmZsb29yKCB1di54ICk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBDbGFtcFRvRWRnZVdyYXBwaW5nOlxuXG5cdFx0XHRcdFx0dXYueCA9IHV2LnggPCAwID8gMCA6IDE7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSBNaXJyb3JlZFJlcGVhdFdyYXBwaW5nOlxuXG5cdFx0XHRcdFx0aWYgKCBNYXRoLmFicyggTWF0aC5mbG9vciggdXYueCApICUgMiApID09PSAxICkge1xuXG5cdFx0XHRcdFx0XHR1di54ID0gTWF0aC5jZWlsKCB1di54ICkgLSB1di54O1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0dXYueCA9IHV2LnggLSBNYXRoLmZsb29yKCB1di54ICk7XG5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggdXYueSA8IDAgfHwgdXYueSA+IDEgKSB7XG5cblx0XHRcdHN3aXRjaCAoIHRoaXMud3JhcFQgKSB7XG5cblx0XHRcdFx0Y2FzZSBSZXBlYXRXcmFwcGluZzpcblxuXHRcdFx0XHRcdHV2LnkgPSB1di55IC0gTWF0aC5mbG9vciggdXYueSApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgQ2xhbXBUb0VkZ2VXcmFwcGluZzpcblxuXHRcdFx0XHRcdHV2LnkgPSB1di55IDwgMCA/IDAgOiAxO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgTWlycm9yZWRSZXBlYXRXcmFwcGluZzpcblxuXHRcdFx0XHRcdGlmICggTWF0aC5hYnMoIE1hdGguZmxvb3IoIHV2LnkgKSAlIDIgKSA9PT0gMSApIHtcblxuXHRcdFx0XHRcdFx0dXYueSA9IE1hdGguY2VpbCggdXYueSApIC0gdXYueTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdHV2LnkgPSB1di55IC0gTWF0aC5mbG9vciggdXYueSApO1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuZmxpcFkgKSB7XG5cblx0XHRcdHV2LnkgPSAxIC0gdXYueTtcblxuXHRcdH1cblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIHN1cGVyZWdnYmVydCAvIGh0dHA6Ly93d3cucGF1bGJydW50LmNvLnVrL1xuICogQGF1dGhvciBwaGlsb2diIC8gaHR0cDovL2Jsb2cudGhlaml0Lm9yZy9cbiAqIEBhdXRob3IgbWlrYWVsIGVtdGluZ2VyIC8gaHR0cDovL2dvbW8uc2UvXG4gKiBAYXV0aG9yIGVncmFldGhlciAvIGh0dHA6Ly9lZ3JhZXRoZXIuY29tL1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKi9cblxuZnVuY3Rpb24gVmVjdG9yNCggeCwgeSwgeiwgdyApIHtcblxuXHR0aGlzLnggPSB4IHx8IDA7XG5cdHRoaXMueSA9IHkgfHwgMDtcblx0dGhpcy56ID0geiB8fCAwO1xuXHR0aGlzLncgPSAoIHcgIT09IHVuZGVmaW5lZCApID8gdyA6IDE7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggVmVjdG9yNC5wcm90b3R5cGUsIHtcblxuXHRpc1ZlY3RvcjQ6IHRydWUsXG5cblx0c2V0OiBmdW5jdGlvbiAoIHgsIHksIHosIHcgKSB7XG5cblx0XHR0aGlzLnggPSB4O1xuXHRcdHRoaXMueSA9IHk7XG5cdFx0dGhpcy56ID0gejtcblx0XHR0aGlzLncgPSB3O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRTY2FsYXI6IGZ1bmN0aW9uICggc2NhbGFyICkge1xuXG5cdFx0dGhpcy54ID0gc2NhbGFyO1xuXHRcdHRoaXMueSA9IHNjYWxhcjtcblx0XHR0aGlzLnogPSBzY2FsYXI7XG5cdFx0dGhpcy53ID0gc2NhbGFyO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRYOiBmdW5jdGlvbiAoIHggKSB7XG5cblx0XHR0aGlzLnggPSB4O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRZOiBmdW5jdGlvbiAoIHkgKSB7XG5cblx0XHR0aGlzLnkgPSB5O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRaOiBmdW5jdGlvbiAoIHogKSB7XG5cblx0XHR0aGlzLnogPSB6O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRXOiBmdW5jdGlvbiAoIHcgKSB7XG5cblx0XHR0aGlzLncgPSB3O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRDb21wb25lbnQ6IGZ1bmN0aW9uICggaW5kZXgsIHZhbHVlICkge1xuXG5cdFx0c3dpdGNoICggaW5kZXggKSB7XG5cblx0XHRcdGNhc2UgMDogdGhpcy54ID0gdmFsdWU7IGJyZWFrO1xuXHRcdFx0Y2FzZSAxOiB0aGlzLnkgPSB2YWx1ZTsgYnJlYWs7XG5cdFx0XHRjYXNlIDI6IHRoaXMueiA9IHZhbHVlOyBicmVhaztcblx0XHRcdGNhc2UgMzogdGhpcy53ID0gdmFsdWU7IGJyZWFrO1xuXHRcdFx0ZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCAnaW5kZXggaXMgb3V0IG9mIHJhbmdlOiAnICsgaW5kZXggKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Z2V0Q29tcG9uZW50OiBmdW5jdGlvbiAoIGluZGV4ICkge1xuXG5cdFx0c3dpdGNoICggaW5kZXggKSB7XG5cblx0XHRcdGNhc2UgMDogcmV0dXJuIHRoaXMueDtcblx0XHRcdGNhc2UgMTogcmV0dXJuIHRoaXMueTtcblx0XHRcdGNhc2UgMjogcmV0dXJuIHRoaXMuejtcblx0XHRcdGNhc2UgMzogcmV0dXJuIHRoaXMudztcblx0XHRcdGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvciggJ2luZGV4IGlzIG91dCBvZiByYW5nZTogJyArIGluZGV4ICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCB0aGlzLngsIHRoaXMueSwgdGhpcy56LCB0aGlzLncgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHRoaXMueCA9IHYueDtcblx0XHR0aGlzLnkgPSB2Lnk7XG5cdFx0dGhpcy56ID0gdi56O1xuXHRcdHRoaXMudyA9ICggdi53ICE9PSB1bmRlZmluZWQgKSA/IHYudyA6IDE7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjQ6IC5hZGQoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5hZGRWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggKz0gdi54O1xuXHRcdHRoaXMueSArPSB2Lnk7XG5cdFx0dGhpcy56ICs9IHYuejtcblx0XHR0aGlzLncgKz0gdi53O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRhZGRTY2FsYXI6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHRoaXMueCArPSBzO1xuXHRcdHRoaXMueSArPSBzO1xuXHRcdHRoaXMueiArPSBzO1xuXHRcdHRoaXMudyArPSBzO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRhZGRWZWN0b3JzOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG5cblx0XHR0aGlzLnggPSBhLnggKyBiLng7XG5cdFx0dGhpcy55ID0gYS55ICsgYi55O1xuXHRcdHRoaXMueiA9IGEueiArIGIuejtcblx0XHR0aGlzLncgPSBhLncgKyBiLnc7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZFNjYWxlZFZlY3RvcjogZnVuY3Rpb24gKCB2LCBzICkge1xuXG5cdFx0dGhpcy54ICs9IHYueCAqIHM7XG5cdFx0dGhpcy55ICs9IHYueSAqIHM7XG5cdFx0dGhpcy56ICs9IHYueiAqIHM7XG5cdFx0dGhpcy53ICs9IHYudyAqIHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHN1YjogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjQ6IC5zdWIoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5zdWJWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5zdWJWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggLT0gdi54O1xuXHRcdHRoaXMueSAtPSB2Lnk7XG5cdFx0dGhpcy56IC09IHYuejtcblx0XHR0aGlzLncgLT0gdi53O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzdWJTY2FsYXI6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHRoaXMueCAtPSBzO1xuXHRcdHRoaXMueSAtPSBzO1xuXHRcdHRoaXMueiAtPSBzO1xuXHRcdHRoaXMudyAtPSBzO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzdWJWZWN0b3JzOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG5cblx0XHR0aGlzLnggPSBhLnggLSBiLng7XG5cdFx0dGhpcy55ID0gYS55IC0gYi55O1xuXHRcdHRoaXMueiA9IGEueiAtIGIuejtcblx0XHR0aGlzLncgPSBhLncgLSBiLnc7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG11bHRpcGx5U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHRoaXMueCAqPSBzY2FsYXI7XG5cdFx0dGhpcy55ICo9IHNjYWxhcjtcblx0XHR0aGlzLnogKj0gc2NhbGFyO1xuXHRcdHRoaXMudyAqPSBzY2FsYXI7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFwcGx5TWF0cml4NDogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLnosIHcgPSB0aGlzLnc7XG5cdFx0dmFyIGUgPSBtLmVsZW1lbnRzO1xuXG5cdFx0dGhpcy54ID0gZVsgMCBdICogeCArIGVbIDQgXSAqIHkgKyBlWyA4IF0gKiB6ICsgZVsgMTIgXSAqIHc7XG5cdFx0dGhpcy55ID0gZVsgMSBdICogeCArIGVbIDUgXSAqIHkgKyBlWyA5IF0gKiB6ICsgZVsgMTMgXSAqIHc7XG5cdFx0dGhpcy56ID0gZVsgMiBdICogeCArIGVbIDYgXSAqIHkgKyBlWyAxMCBdICogeiArIGVbIDE0IF0gKiB3O1xuXHRcdHRoaXMudyA9IGVbIDMgXSAqIHggKyBlWyA3IF0gKiB5ICsgZVsgMTEgXSAqIHogKyBlWyAxNSBdICogdztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGl2aWRlU2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHJldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKCAxIC8gc2NhbGFyICk7XG5cblx0fSxcblxuXHRzZXRBeGlzQW5nbGVGcm9tUXVhdGVybmlvbjogZnVuY3Rpb24gKCBxICkge1xuXG5cdFx0Ly8gaHR0cDovL3d3dy5ldWNsaWRlYW5zcGFjZS5jb20vbWF0aHMvZ2VvbWV0cnkvcm90YXRpb25zL2NvbnZlcnNpb25zL3F1YXRlcm5pb25Ub0FuZ2xlL2luZGV4Lmh0bVxuXG5cdFx0Ly8gcSBpcyBhc3N1bWVkIHRvIGJlIG5vcm1hbGl6ZWRcblxuXHRcdHRoaXMudyA9IDIgKiBNYXRoLmFjb3MoIHEudyApO1xuXG5cdFx0dmFyIHMgPSBNYXRoLnNxcnQoIDEgLSBxLncgKiBxLncgKTtcblxuXHRcdGlmICggcyA8IDAuMDAwMSApIHtcblxuXHRcdFx0IHRoaXMueCA9IDE7XG5cdFx0XHQgdGhpcy55ID0gMDtcblx0XHRcdCB0aGlzLnogPSAwO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0IHRoaXMueCA9IHEueCAvIHM7XG5cdFx0XHQgdGhpcy55ID0gcS55IC8gcztcblx0XHRcdCB0aGlzLnogPSBxLnogLyBzO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRBeGlzQW5nbGVGcm9tUm90YXRpb25NYXRyaXg6IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdC8vIGh0dHA6Ly93d3cuZXVjbGlkZWFuc3BhY2UuY29tL21hdGhzL2dlb21ldHJ5L3JvdGF0aW9ucy9jb252ZXJzaW9ucy9tYXRyaXhUb0FuZ2xlL2luZGV4Lmh0bVxuXG5cdFx0Ly8gYXNzdW1lcyB0aGUgdXBwZXIgM3gzIG9mIG0gaXMgYSBwdXJlIHJvdGF0aW9uIG1hdHJpeCAoaS5lLCB1bnNjYWxlZClcblxuXHRcdHZhciBhbmdsZSwgeCwgeSwgeixcdFx0Ly8gdmFyaWFibGVzIGZvciByZXN1bHRcblx0XHRcdGVwc2lsb24gPSAwLjAxLFx0XHQvLyBtYXJnaW4gdG8gYWxsb3cgZm9yIHJvdW5kaW5nIGVycm9yc1xuXHRcdFx0ZXBzaWxvbjIgPSAwLjEsXHRcdC8vIG1hcmdpbiB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIDAgYW5kIDE4MCBkZWdyZWVzXG5cblx0XHRcdHRlID0gbS5lbGVtZW50cyxcblxuXHRcdFx0bTExID0gdGVbIDAgXSwgbTEyID0gdGVbIDQgXSwgbTEzID0gdGVbIDggXSxcblx0XHRcdG0yMSA9IHRlWyAxIF0sIG0yMiA9IHRlWyA1IF0sIG0yMyA9IHRlWyA5IF0sXG5cdFx0XHRtMzEgPSB0ZVsgMiBdLCBtMzIgPSB0ZVsgNiBdLCBtMzMgPSB0ZVsgMTAgXTtcblxuXHRcdGlmICggKCBNYXRoLmFicyggbTEyIC0gbTIxICkgPCBlcHNpbG9uICkgJiZcblx0XHQgICAgICggTWF0aC5hYnMoIG0xMyAtIG0zMSApIDwgZXBzaWxvbiApICYmXG5cdFx0ICAgICAoIE1hdGguYWJzKCBtMjMgLSBtMzIgKSA8IGVwc2lsb24gKSApIHtcblxuXHRcdFx0Ly8gc2luZ3VsYXJpdHkgZm91bmRcblx0XHRcdC8vIGZpcnN0IGNoZWNrIGZvciBpZGVudGl0eSBtYXRyaXggd2hpY2ggbXVzdCBoYXZlICsxIGZvciBhbGwgdGVybXNcblx0XHRcdC8vIGluIGxlYWRpbmcgZGlhZ29uYWwgYW5kIHplcm8gaW4gb3RoZXIgdGVybXNcblxuXHRcdFx0aWYgKCAoIE1hdGguYWJzKCBtMTIgKyBtMjEgKSA8IGVwc2lsb24yICkgJiZcblx0XHRcdCAgICAgKCBNYXRoLmFicyggbTEzICsgbTMxICkgPCBlcHNpbG9uMiApICYmXG5cdFx0XHQgICAgICggTWF0aC5hYnMoIG0yMyArIG0zMiApIDwgZXBzaWxvbjIgKSAmJlxuXHRcdFx0ICAgICAoIE1hdGguYWJzKCBtMTEgKyBtMjIgKyBtMzMgLSAzICkgPCBlcHNpbG9uMiApICkge1xuXG5cdFx0XHRcdC8vIHRoaXMgc2luZ3VsYXJpdHkgaXMgaWRlbnRpdHkgbWF0cml4IHNvIGFuZ2xlID0gMFxuXG5cdFx0XHRcdHRoaXMuc2V0KCAxLCAwLCAwLCAwICk7XG5cblx0XHRcdFx0cmV0dXJuIHRoaXM7IC8vIHplcm8gYW5nbGUsIGFyYml0cmFyeSBheGlzXG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gb3RoZXJ3aXNlIHRoaXMgc2luZ3VsYXJpdHkgaXMgYW5nbGUgPSAxODBcblxuXHRcdFx0YW5nbGUgPSBNYXRoLlBJO1xuXG5cdFx0XHR2YXIgeHggPSAoIG0xMSArIDEgKSAvIDI7XG5cdFx0XHR2YXIgeXkgPSAoIG0yMiArIDEgKSAvIDI7XG5cdFx0XHR2YXIgenogPSAoIG0zMyArIDEgKSAvIDI7XG5cdFx0XHR2YXIgeHkgPSAoIG0xMiArIG0yMSApIC8gNDtcblx0XHRcdHZhciB4eiA9ICggbTEzICsgbTMxICkgLyA0O1xuXHRcdFx0dmFyIHl6ID0gKCBtMjMgKyBtMzIgKSAvIDQ7XG5cblx0XHRcdGlmICggKCB4eCA+IHl5ICkgJiYgKCB4eCA+IHp6ICkgKSB7XG5cblx0XHRcdFx0Ly8gbTExIGlzIHRoZSBsYXJnZXN0IGRpYWdvbmFsIHRlcm1cblxuXHRcdFx0XHRpZiAoIHh4IDwgZXBzaWxvbiApIHtcblxuXHRcdFx0XHRcdHggPSAwO1xuXHRcdFx0XHRcdHkgPSAwLjcwNzEwNjc4MTtcblx0XHRcdFx0XHR6ID0gMC43MDcxMDY3ODE7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHggPSBNYXRoLnNxcnQoIHh4ICk7XG5cdFx0XHRcdFx0eSA9IHh5IC8geDtcblx0XHRcdFx0XHR6ID0geHogLyB4O1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIGlmICggeXkgPiB6eiApIHtcblxuXHRcdFx0XHQvLyBtMjIgaXMgdGhlIGxhcmdlc3QgZGlhZ29uYWwgdGVybVxuXG5cdFx0XHRcdGlmICggeXkgPCBlcHNpbG9uICkge1xuXG5cdFx0XHRcdFx0eCA9IDAuNzA3MTA2NzgxO1xuXHRcdFx0XHRcdHkgPSAwO1xuXHRcdFx0XHRcdHogPSAwLjcwNzEwNjc4MTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0eSA9IE1hdGguc3FydCggeXkgKTtcblx0XHRcdFx0XHR4ID0geHkgLyB5O1xuXHRcdFx0XHRcdHogPSB5eiAvIHk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIG0zMyBpcyB0aGUgbGFyZ2VzdCBkaWFnb25hbCB0ZXJtIHNvIGJhc2UgcmVzdWx0IG9uIHRoaXNcblxuXHRcdFx0XHRpZiAoIHp6IDwgZXBzaWxvbiApIHtcblxuXHRcdFx0XHRcdHggPSAwLjcwNzEwNjc4MTtcblx0XHRcdFx0XHR5ID0gMC43MDcxMDY3ODE7XG5cdFx0XHRcdFx0eiA9IDA7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHogPSBNYXRoLnNxcnQoIHp6ICk7XG5cdFx0XHRcdFx0eCA9IHh6IC8gejtcblx0XHRcdFx0XHR5ID0geXogLyB6O1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNldCggeCwgeSwgeiwgYW5nbGUgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7IC8vIHJldHVybiAxODAgZGVnIHJvdGF0aW9uXG5cblx0XHR9XG5cblx0XHQvLyBhcyB3ZSBoYXZlIHJlYWNoZWQgaGVyZSB0aGVyZSBhcmUgbm8gc2luZ3VsYXJpdGllcyBzbyB3ZSBjYW4gaGFuZGxlIG5vcm1hbGx5XG5cblx0XHR2YXIgcyA9IE1hdGguc3FydCggKCBtMzIgLSBtMjMgKSAqICggbTMyIC0gbTIzICkgK1xuXHRcdCAgICAgICAgICAgICAgICAgICAoIG0xMyAtIG0zMSApICogKCBtMTMgLSBtMzEgKSArXG5cdFx0ICAgICAgICAgICAgICAgICAgICggbTIxIC0gbTEyICkgKiAoIG0yMSAtIG0xMiApICk7IC8vIHVzZWQgdG8gbm9ybWFsaXplXG5cblx0XHRpZiAoIE1hdGguYWJzKCBzICkgPCAwLjAwMSApIHMgPSAxO1xuXG5cdFx0Ly8gcHJldmVudCBkaXZpZGUgYnkgemVybywgc2hvdWxkIG5vdCBoYXBwZW4gaWYgbWF0cml4IGlzIG9ydGhvZ29uYWwgYW5kIHNob3VsZCBiZVxuXHRcdC8vIGNhdWdodCBieSBzaW5ndWxhcml0eSB0ZXN0IGFib3ZlLCBidXQgSSd2ZSBsZWZ0IGl0IGluIGp1c3QgaW4gY2FzZVxuXG5cdFx0dGhpcy54ID0gKCBtMzIgLSBtMjMgKSAvIHM7XG5cdFx0dGhpcy55ID0gKCBtMTMgLSBtMzEgKSAvIHM7XG5cdFx0dGhpcy56ID0gKCBtMjEgLSBtMTIgKSAvIHM7XG5cdFx0dGhpcy53ID0gTWF0aC5hY29zKCAoIG0xMSArIG0yMiArIG0zMyAtIDEgKSAvIDIgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWluOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1pbiggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1pbiggdGhpcy55LCB2LnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLm1pbiggdGhpcy56LCB2LnogKTtcblx0XHR0aGlzLncgPSBNYXRoLm1pbiggdGhpcy53LCB2LncgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWF4OiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1heCggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1heCggdGhpcy55LCB2LnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLm1heCggdGhpcy56LCB2LnogKTtcblx0XHR0aGlzLncgPSBNYXRoLm1heCggdGhpcy53LCB2LncgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xhbXA6IGZ1bmN0aW9uICggbWluLCBtYXggKSB7XG5cblx0XHQvLyBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgbWluIDwgbWF4LCBpZiB0aGlzIGFzc3VtcHRpb24gaXNuJ3QgdHJ1ZSBpdCB3aWxsIG5vdCBvcGVyYXRlIGNvcnJlY3RseVxuXG5cdFx0dGhpcy54ID0gTWF0aC5tYXgoIG1pbi54LCBNYXRoLm1pbiggbWF4LngsIHRoaXMueCApICk7XG5cdFx0dGhpcy55ID0gTWF0aC5tYXgoIG1pbi55LCBNYXRoLm1pbiggbWF4LnksIHRoaXMueSApICk7XG5cdFx0dGhpcy56ID0gTWF0aC5tYXgoIG1pbi56LCBNYXRoLm1pbiggbWF4LnosIHRoaXMueiApICk7XG5cdFx0dGhpcy53ID0gTWF0aC5tYXgoIG1pbi53LCBNYXRoLm1pbiggbWF4LncsIHRoaXMudyApICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsYW1wU2NhbGFyOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbWluID0gbmV3IFZlY3RvcjQoKTtcblx0XHR2YXIgbWF4ID0gbmV3IFZlY3RvcjQoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBjbGFtcFNjYWxhciggbWluVmFsLCBtYXhWYWwgKSB7XG5cblx0XHRcdG1pbi5zZXQoIG1pblZhbCwgbWluVmFsLCBtaW5WYWwsIG1pblZhbCApO1xuXHRcdFx0bWF4LnNldCggbWF4VmFsLCBtYXhWYWwsIG1heFZhbCwgbWF4VmFsICk7XG5cblx0XHRcdHJldHVybiB0aGlzLmNsYW1wKCBtaW4sIG1heCApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Zmxvb3I6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9IE1hdGguZmxvb3IoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9IE1hdGguZmxvb3IoIHRoaXMueSApO1xuXHRcdHRoaXMueiA9IE1hdGguZmxvb3IoIHRoaXMueiApO1xuXHRcdHRoaXMudyA9IE1hdGguZmxvb3IoIHRoaXMudyApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjZWlsOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLmNlaWwoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9IE1hdGguY2VpbCggdGhpcy55ICk7XG5cdFx0dGhpcy56ID0gTWF0aC5jZWlsKCB0aGlzLnogKTtcblx0XHR0aGlzLncgPSBNYXRoLmNlaWwoIHRoaXMudyApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRyb3VuZDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy54ID0gTWF0aC5yb3VuZCggdGhpcy54ICk7XG5cdFx0dGhpcy55ID0gTWF0aC5yb3VuZCggdGhpcy55ICk7XG5cdFx0dGhpcy56ID0gTWF0aC5yb3VuZCggdGhpcy56ICk7XG5cdFx0dGhpcy53ID0gTWF0aC5yb3VuZCggdGhpcy53ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHJvdW5kVG9aZXJvOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSAoIHRoaXMueCA8IDAgKSA/IE1hdGguY2VpbCggdGhpcy54ICkgOiBNYXRoLmZsb29yKCB0aGlzLnggKTtcblx0XHR0aGlzLnkgPSAoIHRoaXMueSA8IDAgKSA/IE1hdGguY2VpbCggdGhpcy55ICkgOiBNYXRoLmZsb29yKCB0aGlzLnkgKTtcblx0XHR0aGlzLnogPSAoIHRoaXMueiA8IDAgKSA/IE1hdGguY2VpbCggdGhpcy56ICkgOiBNYXRoLmZsb29yKCB0aGlzLnogKTtcblx0XHR0aGlzLncgPSAoIHRoaXMudyA8IDAgKSA/IE1hdGguY2VpbCggdGhpcy53ICkgOiBNYXRoLmZsb29yKCB0aGlzLncgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bmVnYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSAtIHRoaXMueDtcblx0XHR0aGlzLnkgPSAtIHRoaXMueTtcblx0XHR0aGlzLnogPSAtIHRoaXMuejtcblx0XHR0aGlzLncgPSAtIHRoaXMudztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZG90OiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy54ICogdi54ICsgdGhpcy55ICogdi55ICsgdGhpcy56ICogdi56ICsgdGhpcy53ICogdi53O1xuXG5cdH0sXG5cblx0bGVuZ3RoU3E6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnggKiB0aGlzLnggKyB0aGlzLnkgKiB0aGlzLnkgKyB0aGlzLnogKiB0aGlzLnogKyB0aGlzLncgKiB0aGlzLnc7XG5cblx0fSxcblxuXHRsZW5ndGg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBNYXRoLnNxcnQoIHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueSArIHRoaXMueiAqIHRoaXMueiArIHRoaXMudyAqIHRoaXMudyApO1xuXG5cdH0sXG5cblx0bGVuZ3RoTWFuaGF0dGFuOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gTWF0aC5hYnMoIHRoaXMueCApICsgTWF0aC5hYnMoIHRoaXMueSApICsgTWF0aC5hYnMoIHRoaXMueiApICsgTWF0aC5hYnMoIHRoaXMudyApO1xuXG5cdH0sXG5cblx0bm9ybWFsaXplOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIoIHRoaXMubGVuZ3RoKCkgKTtcblxuXHR9LFxuXG5cdHNldExlbmd0aDogZnVuY3Rpb24gKCBsZW5ndGggKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVNjYWxhciggbGVuZ3RoIC8gdGhpcy5sZW5ndGgoKSApO1xuXG5cdH0sXG5cblx0bGVycDogZnVuY3Rpb24gKCB2LCBhbHBoYSApIHtcblxuXHRcdHRoaXMueCArPSAoIHYueCAtIHRoaXMueCApICogYWxwaGE7XG5cdFx0dGhpcy55ICs9ICggdi55IC0gdGhpcy55ICkgKiBhbHBoYTtcblx0XHR0aGlzLnogKz0gKCB2LnogLSB0aGlzLnogKSAqIGFscGhhO1xuXHRcdHRoaXMudyArPSAoIHYudyAtIHRoaXMudyApICogYWxwaGE7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGxlcnBWZWN0b3JzOiBmdW5jdGlvbiAoIHYxLCB2MiwgYWxwaGEgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5zdWJWZWN0b3JzKCB2MiwgdjEgKS5tdWx0aXBseVNjYWxhciggYWxwaGEgKS5hZGQoIHYxICk7XG5cblx0fSxcblxuXHRlcXVhbHM6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHJldHVybiAoICggdi54ID09PSB0aGlzLnggKSAmJiAoIHYueSA9PT0gdGhpcy55ICkgJiYgKCB2LnogPT09IHRoaXMueiApICYmICggdi53ID09PSB0aGlzLncgKSApO1xuXG5cdH0sXG5cblx0ZnJvbUFycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHRoaXMueCA9IGFycmF5WyBvZmZzZXQgXTtcblx0XHR0aGlzLnkgPSBhcnJheVsgb2Zmc2V0ICsgMSBdO1xuXHRcdHRoaXMueiA9IGFycmF5WyBvZmZzZXQgKyAyIF07XG5cdFx0dGhpcy53ID0gYXJyYXlbIG9mZnNldCArIDMgXTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0dG9BcnJheTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBhcnJheSA9PT0gdW5kZWZpbmVkICkgYXJyYXkgPSBbXTtcblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdGFycmF5WyBvZmZzZXQgXSA9IHRoaXMueDtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMSBdID0gdGhpcy55O1xuXHRcdGFycmF5WyBvZmZzZXQgKyAyIF0gPSB0aGlzLno7XG5cdFx0YXJyYXlbIG9mZnNldCArIDMgXSA9IHRoaXMudztcblxuXHRcdHJldHVybiBhcnJheTtcblxuXHR9LFxuXG5cdGZyb21CdWZmZXJBdHRyaWJ1dGU6IGZ1bmN0aW9uICggYXR0cmlidXRlLCBpbmRleCwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBvZmZzZXQgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVmVjdG9yNDogb2Zmc2V0IGhhcyBiZWVuIHJlbW92ZWQgZnJvbSAuZnJvbUJ1ZmZlckF0dHJpYnV0ZSgpLicgKTtcblxuXHRcdH1cblxuXHRcdHRoaXMueCA9IGF0dHJpYnV0ZS5nZXRYKCBpbmRleCApO1xuXHRcdHRoaXMueSA9IGF0dHJpYnV0ZS5nZXRZKCBpbmRleCApO1xuXHRcdHRoaXMueiA9IGF0dHJpYnV0ZS5nZXRaKCBpbmRleCApO1xuXHRcdHRoaXMudyA9IGF0dHJpYnV0ZS5nZXRXKCBpbmRleCApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBzemltZWsgLyBodHRwczovL2dpdGh1Yi5jb20vc3ppbWVrL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgTWFyaXVzIEtpbnRlbCAvIGh0dHBzOi8vZ2l0aHViLmNvbS9raW50ZWxcbiAqL1xuXG4vKlxuIEluIG9wdGlvbnMsIHdlIGNhbiBzcGVjaWZ5OlxuICogVGV4dHVyZSBwYXJhbWV0ZXJzIGZvciBhbiBhdXRvLWdlbmVyYXRlZCB0YXJnZXQgdGV4dHVyZVxuICogZGVwdGhCdWZmZXIvc3RlbmNpbEJ1ZmZlcjogQm9vbGVhbnMgdG8gaW5kaWNhdGUgaWYgd2Ugc2hvdWxkIGdlbmVyYXRlIHRoZXNlIGJ1ZmZlcnNcbiovXG5mdW5jdGlvbiBXZWJHTFJlbmRlclRhcmdldCggd2lkdGgsIGhlaWdodCwgb3B0aW9ucyApIHtcblxuXHR0aGlzLnV1aWQgPSBfTWF0aC5nZW5lcmF0ZVVVSUQoKTtcblxuXHR0aGlzLndpZHRoID0gd2lkdGg7XG5cdHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG5cdHRoaXMuc2Npc3NvciA9IG5ldyBWZWN0b3I0KCAwLCAwLCB3aWR0aCwgaGVpZ2h0ICk7XG5cdHRoaXMuc2Npc3NvclRlc3QgPSBmYWxzZTtcblxuXHR0aGlzLnZpZXdwb3J0ID0gbmV3IFZlY3RvcjQoIDAsIDAsIHdpZHRoLCBoZWlnaHQgKTtcblxuXHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXHRpZiAoIG9wdGlvbnMubWluRmlsdGVyID09PSB1bmRlZmluZWQgKSBvcHRpb25zLm1pbkZpbHRlciA9IExpbmVhckZpbHRlcjtcblxuXHR0aGlzLnRleHR1cmUgPSBuZXcgVGV4dHVyZSggdW5kZWZpbmVkLCB1bmRlZmluZWQsIG9wdGlvbnMud3JhcFMsIG9wdGlvbnMud3JhcFQsIG9wdGlvbnMubWFnRmlsdGVyLCBvcHRpb25zLm1pbkZpbHRlciwgb3B0aW9ucy5mb3JtYXQsIG9wdGlvbnMudHlwZSwgb3B0aW9ucy5hbmlzb3Ryb3B5LCBvcHRpb25zLmVuY29kaW5nICk7XG5cblx0dGhpcy5kZXB0aEJ1ZmZlciA9IG9wdGlvbnMuZGVwdGhCdWZmZXIgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGVwdGhCdWZmZXIgOiB0cnVlO1xuXHR0aGlzLnN0ZW5jaWxCdWZmZXIgPSBvcHRpb25zLnN0ZW5jaWxCdWZmZXIgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3RlbmNpbEJ1ZmZlciA6IHRydWU7XG5cdHRoaXMuZGVwdGhUZXh0dXJlID0gb3B0aW9ucy5kZXB0aFRleHR1cmUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGVwdGhUZXh0dXJlIDogbnVsbDtcblxufVxuXG5PYmplY3QuYXNzaWduKCBXZWJHTFJlbmRlclRhcmdldC5wcm90b3R5cGUsIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUsIHtcblxuXHRpc1dlYkdMUmVuZGVyVGFyZ2V0OiB0cnVlLFxuXG5cdHNldFNpemU6IGZ1bmN0aW9uICggd2lkdGgsIGhlaWdodCApIHtcblxuXHRcdGlmICggdGhpcy53aWR0aCAhPT0gd2lkdGggfHwgdGhpcy5oZWlnaHQgIT09IGhlaWdodCApIHtcblxuXHRcdFx0dGhpcy53aWR0aCA9IHdpZHRoO1xuXHRcdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG5cblx0XHRcdHRoaXMuZGlzcG9zZSgpO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy52aWV3cG9ydC5zZXQoIDAsIDAsIHdpZHRoLCBoZWlnaHQgKTtcblx0XHR0aGlzLnNjaXNzb3Iuc2V0KCAwLCAwLCB3aWR0aCwgaGVpZ2h0ICk7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR0aGlzLndpZHRoID0gc291cmNlLndpZHRoO1xuXHRcdHRoaXMuaGVpZ2h0ID0gc291cmNlLmhlaWdodDtcblxuXHRcdHRoaXMudmlld3BvcnQuY29weSggc291cmNlLnZpZXdwb3J0ICk7XG5cblx0XHR0aGlzLnRleHR1cmUgPSBzb3VyY2UudGV4dHVyZS5jbG9uZSgpO1xuXG5cdFx0dGhpcy5kZXB0aEJ1ZmZlciA9IHNvdXJjZS5kZXB0aEJ1ZmZlcjtcblx0XHR0aGlzLnN0ZW5jaWxCdWZmZXIgPSBzb3VyY2Uuc3RlbmNpbEJ1ZmZlcjtcblx0XHR0aGlzLmRlcHRoVGV4dHVyZSA9IHNvdXJjZS5kZXB0aFRleHR1cmU7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGRpc3Bvc2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZGlzcGF0Y2hFdmVudCggeyB0eXBlOiAnZGlzcG9zZScgfSApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb21cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTFJlbmRlclRhcmdldEN1YmUoIHdpZHRoLCBoZWlnaHQsIG9wdGlvbnMgKSB7XG5cblx0V2ViR0xSZW5kZXJUYXJnZXQuY2FsbCggdGhpcywgd2lkdGgsIGhlaWdodCwgb3B0aW9ucyApO1xuXG5cdHRoaXMuYWN0aXZlQ3ViZUZhY2UgPSAwOyAvLyBQWCAwLCBOWCAxLCBQWSAyLCBOWSAzLCBQWiA0LCBOWiA1XG5cdHRoaXMuYWN0aXZlTWlwTWFwTGV2ZWwgPSAwO1xuXG59XG5cbldlYkdMUmVuZGVyVGFyZ2V0Q3ViZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBXZWJHTFJlbmRlclRhcmdldC5wcm90b3R5cGUgKTtcbldlYkdMUmVuZGVyVGFyZ2V0Q3ViZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBXZWJHTFJlbmRlclRhcmdldEN1YmU7XG5cbldlYkdMUmVuZGVyVGFyZ2V0Q3ViZS5wcm90b3R5cGUuaXNXZWJHTFJlbmRlclRhcmdldEN1YmUgPSB0cnVlO1xuXG4vKipcbiAqIEBhdXRob3IgbWlrYWVsIGVtdGluZ2VyIC8gaHR0cDovL2dvbW8uc2UvXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvXG4gKi9cblxuZnVuY3Rpb24gUXVhdGVybmlvbiggeCwgeSwgeiwgdyApIHtcblxuXHR0aGlzLl94ID0geCB8fCAwO1xuXHR0aGlzLl95ID0geSB8fCAwO1xuXHR0aGlzLl96ID0geiB8fCAwO1xuXHR0aGlzLl93ID0gKCB3ICE9PSB1bmRlZmluZWQgKSA/IHcgOiAxO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFF1YXRlcm5pb24sIHtcblxuXHRzbGVycDogZnVuY3Rpb24gKCBxYSwgcWIsIHFtLCB0ICkge1xuXG5cdFx0cmV0dXJuIHFtLmNvcHkoIHFhICkuc2xlcnAoIHFiLCB0ICk7XG5cblx0fSxcblxuXHRzbGVycEZsYXQ6IGZ1bmN0aW9uICggZHN0LCBkc3RPZmZzZXQsIHNyYzAsIHNyY09mZnNldDAsIHNyYzEsIHNyY09mZnNldDEsIHQgKSB7XG5cblx0XHQvLyBmdXp6LWZyZWUsIGFycmF5LWJhc2VkIFF1YXRlcm5pb24gU0xFUlAgb3BlcmF0aW9uXG5cblx0XHR2YXIgeDAgPSBzcmMwWyBzcmNPZmZzZXQwICsgMCBdLFxuXHRcdFx0eTAgPSBzcmMwWyBzcmNPZmZzZXQwICsgMSBdLFxuXHRcdFx0ejAgPSBzcmMwWyBzcmNPZmZzZXQwICsgMiBdLFxuXHRcdFx0dzAgPSBzcmMwWyBzcmNPZmZzZXQwICsgMyBdLFxuXG5cdFx0XHR4MSA9IHNyYzFbIHNyY09mZnNldDEgKyAwIF0sXG5cdFx0XHR5MSA9IHNyYzFbIHNyY09mZnNldDEgKyAxIF0sXG5cdFx0XHR6MSA9IHNyYzFbIHNyY09mZnNldDEgKyAyIF0sXG5cdFx0XHR3MSA9IHNyYzFbIHNyY09mZnNldDEgKyAzIF07XG5cblx0XHRpZiAoIHcwICE9PSB3MSB8fCB4MCAhPT0geDEgfHwgeTAgIT09IHkxIHx8IHowICE9PSB6MSApIHtcblxuXHRcdFx0dmFyIHMgPSAxIC0gdCxcblxuXHRcdFx0XHRjb3MgPSB4MCAqIHgxICsgeTAgKiB5MSArIHowICogejEgKyB3MCAqIHcxLFxuXG5cdFx0XHRcdGRpciA9ICggY29zID49IDAgPyAxIDogLSAxICksXG5cdFx0XHRcdHNxclNpbiA9IDEgLSBjb3MgKiBjb3M7XG5cblx0XHRcdC8vIFNraXAgdGhlIFNsZXJwIGZvciB0aW55IHN0ZXBzIHRvIGF2b2lkIG51bWVyaWMgcHJvYmxlbXM6XG5cdFx0XHRpZiAoIHNxclNpbiA+IE51bWJlci5FUFNJTE9OICkge1xuXG5cdFx0XHRcdHZhciBzaW4gPSBNYXRoLnNxcnQoIHNxclNpbiApLFxuXHRcdFx0XHRcdGxlbiA9IE1hdGguYXRhbjIoIHNpbiwgY29zICogZGlyICk7XG5cblx0XHRcdFx0cyA9IE1hdGguc2luKCBzICogbGVuICkgLyBzaW47XG5cdFx0XHRcdHQgPSBNYXRoLnNpbiggdCAqIGxlbiApIC8gc2luO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciB0RGlyID0gdCAqIGRpcjtcblxuXHRcdFx0eDAgPSB4MCAqIHMgKyB4MSAqIHREaXI7XG5cdFx0XHR5MCA9IHkwICogcyArIHkxICogdERpcjtcblx0XHRcdHowID0gejAgKiBzICsgejEgKiB0RGlyO1xuXHRcdFx0dzAgPSB3MCAqIHMgKyB3MSAqIHREaXI7XG5cblx0XHRcdC8vIE5vcm1hbGl6ZSBpbiBjYXNlIHdlIGp1c3QgZGlkIGEgbGVycDpcblx0XHRcdGlmICggcyA9PT0gMSAtIHQgKSB7XG5cblx0XHRcdFx0dmFyIGYgPSAxIC8gTWF0aC5zcXJ0KCB4MCAqIHgwICsgeTAgKiB5MCArIHowICogejAgKyB3MCAqIHcwICk7XG5cblx0XHRcdFx0eDAgKj0gZjtcblx0XHRcdFx0eTAgKj0gZjtcblx0XHRcdFx0ejAgKj0gZjtcblx0XHRcdFx0dzAgKj0gZjtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0ZHN0WyBkc3RPZmZzZXQgXSA9IHgwO1xuXHRcdGRzdFsgZHN0T2Zmc2V0ICsgMSBdID0geTA7XG5cdFx0ZHN0WyBkc3RPZmZzZXQgKyAyIF0gPSB6MDtcblx0XHRkc3RbIGRzdE9mZnNldCArIDMgXSA9IHcwO1xuXG5cdH1cblxufSApO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggUXVhdGVybmlvbi5wcm90b3R5cGUsIHtcblxuXHR4OiB7XG5cblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuX3g7XG5cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHR0aGlzLl94ID0gdmFsdWU7XG5cdFx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdHk6IHtcblxuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5feTtcblxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdHRoaXMuX3kgPSB2YWx1ZTtcblx0XHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0ejoge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLl96O1xuXG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0dGhpcy5feiA9IHZhbHVlO1xuXHRcdFx0dGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHR9XG5cblx0fSxcblxuXHR3OiB7XG5cblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuX3c7XG5cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHR0aGlzLl93ID0gdmFsdWU7XG5cdFx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdH1cblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggUXVhdGVybmlvbi5wcm90b3R5cGUsIHtcblxuXHRzZXQ6IGZ1bmN0aW9uICggeCwgeSwgeiwgdyApIHtcblxuXHRcdHRoaXMuX3ggPSB4O1xuXHRcdHRoaXMuX3kgPSB5O1xuXHRcdHRoaXMuX3ogPSB6O1xuXHRcdHRoaXMuX3cgPSB3O1xuXG5cdFx0dGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoIHRoaXMuX3gsIHRoaXMuX3ksIHRoaXMuX3osIHRoaXMuX3cgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggcXVhdGVybmlvbiApIHtcblxuXHRcdHRoaXMuX3ggPSBxdWF0ZXJuaW9uLng7XG5cdFx0dGhpcy5feSA9IHF1YXRlcm5pb24ueTtcblx0XHR0aGlzLl96ID0gcXVhdGVybmlvbi56O1xuXHRcdHRoaXMuX3cgPSBxdWF0ZXJuaW9uLnc7XG5cblx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbUV1bGVyOiBmdW5jdGlvbiAoIGV1bGVyLCB1cGRhdGUgKSB7XG5cblx0XHRpZiAoICggZXVsZXIgJiYgZXVsZXIuaXNFdWxlciApID09PSBmYWxzZSApIHtcblxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCAnVEhSRUUuUXVhdGVybmlvbjogLnNldEZyb21FdWxlcigpIG5vdyBleHBlY3RzIGFuIEV1bGVyIHJvdGF0aW9uIHJhdGhlciB0aGFuIGEgVmVjdG9yMyBhbmQgb3JkZXIuJyApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHggPSBldWxlci5feCwgeSA9IGV1bGVyLl95LCB6ID0gZXVsZXIuX3osIG9yZGVyID0gZXVsZXIub3JkZXI7XG5cblx0XHQvLyBodHRwOi8vd3d3Lm1hdGh3b3Jrcy5jb20vbWF0bGFiY2VudHJhbC9maWxlZXhjaGFuZ2UvXG5cdFx0Ly8gXHQyMDY5Ni1mdW5jdGlvbi10by1jb252ZXJ0LWJldHdlZW4tZGNtLWV1bGVyLWFuZ2xlcy1xdWF0ZXJuaW9ucy1hbmQtZXVsZXItdmVjdG9ycy9cblx0XHQvL1x0Y29udGVudC9TcGluQ2FsYy5tXG5cblx0XHR2YXIgY29zID0gTWF0aC5jb3M7XG5cdFx0dmFyIHNpbiA9IE1hdGguc2luO1xuXG5cdFx0dmFyIGMxID0gY29zKCB4IC8gMiApO1xuXHRcdHZhciBjMiA9IGNvcyggeSAvIDIgKTtcblx0XHR2YXIgYzMgPSBjb3MoIHogLyAyICk7XG5cblx0XHR2YXIgczEgPSBzaW4oIHggLyAyICk7XG5cdFx0dmFyIHMyID0gc2luKCB5IC8gMiApO1xuXHRcdHZhciBzMyA9IHNpbiggeiAvIDIgKTtcblxuXHRcdGlmICggb3JkZXIgPT09ICdYWVonICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzICsgYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyAtIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgKyBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzIC0gczEgKiBzMiAqIHMzO1xuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdZWFonICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzICsgYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyAtIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgLSBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzICsgczEgKiBzMiAqIHMzO1xuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdaWFknICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzIC0gYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyArIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgKyBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzIC0gczEgKiBzMiAqIHMzO1xuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdaWVgnICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzIC0gYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyArIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgLSBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzICsgczEgKiBzMiAqIHMzO1xuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdZWlgnICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzICsgYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyArIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgLSBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzIC0gczEgKiBzMiAqIHMzO1xuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdYWlknICkge1xuXG5cdFx0XHR0aGlzLl94ID0gczEgKiBjMiAqIGMzIC0gYzEgKiBzMiAqIHMzO1xuXHRcdFx0dGhpcy5feSA9IGMxICogczIgKiBjMyAtIHMxICogYzIgKiBzMztcblx0XHRcdHRoaXMuX3ogPSBjMSAqIGMyICogczMgKyBzMSAqIHMyICogYzM7XG5cdFx0XHR0aGlzLl93ID0gYzEgKiBjMiAqIGMzICsgczEgKiBzMiAqIHMzO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCB1cGRhdGUgIT09IGZhbHNlICkgdGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21BeGlzQW5nbGU6IGZ1bmN0aW9uICggYXhpcywgYW5nbGUgKSB7XG5cblx0XHQvLyBodHRwOi8vd3d3LmV1Y2xpZGVhbnNwYWNlLmNvbS9tYXRocy9nZW9tZXRyeS9yb3RhdGlvbnMvY29udmVyc2lvbnMvYW5nbGVUb1F1YXRlcm5pb24vaW5kZXguaHRtXG5cblx0XHQvLyBhc3N1bWVzIGF4aXMgaXMgbm9ybWFsaXplZFxuXG5cdFx0dmFyIGhhbGZBbmdsZSA9IGFuZ2xlIC8gMiwgcyA9IE1hdGguc2luKCBoYWxmQW5nbGUgKTtcblxuXHRcdHRoaXMuX3ggPSBheGlzLnggKiBzO1xuXHRcdHRoaXMuX3kgPSBheGlzLnkgKiBzO1xuXHRcdHRoaXMuX3ogPSBheGlzLnogKiBzO1xuXHRcdHRoaXMuX3cgPSBNYXRoLmNvcyggaGFsZkFuZ2xlICk7XG5cblx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbVJvdGF0aW9uTWF0cml4OiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHQvLyBodHRwOi8vd3d3LmV1Y2xpZGVhbnNwYWNlLmNvbS9tYXRocy9nZW9tZXRyeS9yb3RhdGlvbnMvY29udmVyc2lvbnMvbWF0cml4VG9RdWF0ZXJuaW9uL2luZGV4Lmh0bVxuXG5cdFx0Ly8gYXNzdW1lcyB0aGUgdXBwZXIgM3gzIG9mIG0gaXMgYSBwdXJlIHJvdGF0aW9uIG1hdHJpeCAoaS5lLCB1bnNjYWxlZClcblxuXHRcdHZhciB0ZSA9IG0uZWxlbWVudHMsXG5cblx0XHRcdG0xMSA9IHRlWyAwIF0sIG0xMiA9IHRlWyA0IF0sIG0xMyA9IHRlWyA4IF0sXG5cdFx0XHRtMjEgPSB0ZVsgMSBdLCBtMjIgPSB0ZVsgNSBdLCBtMjMgPSB0ZVsgOSBdLFxuXHRcdFx0bTMxID0gdGVbIDIgXSwgbTMyID0gdGVbIDYgXSwgbTMzID0gdGVbIDEwIF0sXG5cblx0XHRcdHRyYWNlID0gbTExICsgbTIyICsgbTMzLFxuXHRcdFx0cztcblxuXHRcdGlmICggdHJhY2UgPiAwICkge1xuXG5cdFx0XHRzID0gMC41IC8gTWF0aC5zcXJ0KCB0cmFjZSArIDEuMCApO1xuXG5cdFx0XHR0aGlzLl93ID0gMC4yNSAvIHM7XG5cdFx0XHR0aGlzLl94ID0gKCBtMzIgLSBtMjMgKSAqIHM7XG5cdFx0XHR0aGlzLl95ID0gKCBtMTMgLSBtMzEgKSAqIHM7XG5cdFx0XHR0aGlzLl96ID0gKCBtMjEgLSBtMTIgKSAqIHM7XG5cblx0XHR9IGVsc2UgaWYgKCBtMTEgPiBtMjIgJiYgbTExID4gbTMzICkge1xuXG5cdFx0XHRzID0gMi4wICogTWF0aC5zcXJ0KCAxLjAgKyBtMTEgLSBtMjIgLSBtMzMgKTtcblxuXHRcdFx0dGhpcy5fdyA9ICggbTMyIC0gbTIzICkgLyBzO1xuXHRcdFx0dGhpcy5feCA9IDAuMjUgKiBzO1xuXHRcdFx0dGhpcy5feSA9ICggbTEyICsgbTIxICkgLyBzO1xuXHRcdFx0dGhpcy5feiA9ICggbTEzICsgbTMxICkgLyBzO1xuXG5cdFx0fSBlbHNlIGlmICggbTIyID4gbTMzICkge1xuXG5cdFx0XHRzID0gMi4wICogTWF0aC5zcXJ0KCAxLjAgKyBtMjIgLSBtMTEgLSBtMzMgKTtcblxuXHRcdFx0dGhpcy5fdyA9ICggbTEzIC0gbTMxICkgLyBzO1xuXHRcdFx0dGhpcy5feCA9ICggbTEyICsgbTIxICkgLyBzO1xuXHRcdFx0dGhpcy5feSA9IDAuMjUgKiBzO1xuXHRcdFx0dGhpcy5feiA9ICggbTIzICsgbTMyICkgLyBzO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0cyA9IDIuMCAqIE1hdGguc3FydCggMS4wICsgbTMzIC0gbTExIC0gbTIyICk7XG5cblx0XHRcdHRoaXMuX3cgPSAoIG0yMSAtIG0xMiApIC8gcztcblx0XHRcdHRoaXMuX3ggPSAoIG0xMyArIG0zMSApIC8gcztcblx0XHRcdHRoaXMuX3kgPSAoIG0yMyArIG0zMiApIC8gcztcblx0XHRcdHRoaXMuX3ogPSAwLjI1ICogcztcblxuXHRcdH1cblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tVW5pdFZlY3RvcnM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIGFzc3VtZXMgZGlyZWN0aW9uIHZlY3RvcnMgdkZyb20gYW5kIHZUbyBhcmUgbm9ybWFsaXplZFxuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgcjtcblxuXHRcdHZhciBFUFMgPSAwLjAwMDAwMTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBzZXRGcm9tVW5pdFZlY3RvcnMoIHZGcm9tLCB2VG8gKSB7XG5cblx0XHRcdGlmICggdjEgPT09IHVuZGVmaW5lZCApIHYxID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0ciA9IHZGcm9tLmRvdCggdlRvICkgKyAxO1xuXG5cdFx0XHRpZiAoIHIgPCBFUFMgKSB7XG5cblx0XHRcdFx0ciA9IDA7XG5cblx0XHRcdFx0aWYgKCBNYXRoLmFicyggdkZyb20ueCApID4gTWF0aC5hYnMoIHZGcm9tLnogKSApIHtcblxuXHRcdFx0XHRcdHYxLnNldCggLSB2RnJvbS55LCB2RnJvbS54LCAwICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHYxLnNldCggMCwgLSB2RnJvbS56LCB2RnJvbS55ICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHYxLmNyb3NzVmVjdG9ycyggdkZyb20sIHZUbyApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuX3ggPSB2MS54O1xuXHRcdFx0dGhpcy5feSA9IHYxLnk7XG5cdFx0XHR0aGlzLl96ID0gdjEuejtcblx0XHRcdHRoaXMuX3cgPSByO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5ub3JtYWxpemUoKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGludmVyc2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLmNvbmp1Z2F0ZSgpLm5vcm1hbGl6ZSgpO1xuXG5cdH0sXG5cblx0Y29uanVnYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLl94ICo9IC0gMTtcblx0XHR0aGlzLl95ICo9IC0gMTtcblx0XHR0aGlzLl96ICo9IC0gMTtcblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRkb3Q6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHJldHVybiB0aGlzLl94ICogdi5feCArIHRoaXMuX3kgKiB2Ll95ICsgdGhpcy5feiAqIHYuX3ogKyB0aGlzLl93ICogdi5fdztcblxuXHR9LFxuXG5cdGxlbmd0aFNxOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5feCAqIHRoaXMuX3ggKyB0aGlzLl95ICogdGhpcy5feSArIHRoaXMuX3ogKiB0aGlzLl96ICsgdGhpcy5fdyAqIHRoaXMuX3c7XG5cblx0fSxcblxuXHRsZW5ndGg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBNYXRoLnNxcnQoIHRoaXMuX3ggKiB0aGlzLl94ICsgdGhpcy5feSAqIHRoaXMuX3kgKyB0aGlzLl96ICogdGhpcy5feiArIHRoaXMuX3cgKiB0aGlzLl93ICk7XG5cblx0fSxcblxuXHRub3JtYWxpemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBsID0gdGhpcy5sZW5ndGgoKTtcblxuXHRcdGlmICggbCA9PT0gMCApIHtcblxuXHRcdFx0dGhpcy5feCA9IDA7XG5cdFx0XHR0aGlzLl95ID0gMDtcblx0XHRcdHRoaXMuX3ogPSAwO1xuXHRcdFx0dGhpcy5fdyA9IDE7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRsID0gMSAvIGw7XG5cblx0XHRcdHRoaXMuX3ggPSB0aGlzLl94ICogbDtcblx0XHRcdHRoaXMuX3kgPSB0aGlzLl95ICogbDtcblx0XHRcdHRoaXMuX3ogPSB0aGlzLl96ICogbDtcblx0XHRcdHRoaXMuX3cgPSB0aGlzLl93ICogbDtcblxuXHRcdH1cblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtdWx0aXBseTogZnVuY3Rpb24gKCBxLCBwICkge1xuXG5cdFx0aWYgKCBwICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlF1YXRlcm5pb246IC5tdWx0aXBseSgpIG5vdyBvbmx5IGFjY2VwdHMgb25lIGFyZ3VtZW50LiBVc2UgLm11bHRpcGx5UXVhdGVybmlvbnMoIGEsIGIgKSBpbnN0ZWFkLicgKTtcblx0XHRcdHJldHVybiB0aGlzLm11bHRpcGx5UXVhdGVybmlvbnMoIHEsIHAgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLm11bHRpcGx5UXVhdGVybmlvbnMoIHRoaXMsIHEgKTtcblxuXHR9LFxuXG5cdHByZW11bHRpcGx5OiBmdW5jdGlvbiAoIHEgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVF1YXRlcm5pb25zKCBxLCB0aGlzICk7XG5cblx0fSxcblxuXHRtdWx0aXBseVF1YXRlcm5pb25zOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG5cblx0XHQvLyBmcm9tIGh0dHA6Ly93d3cuZXVjbGlkZWFuc3BhY2UuY29tL21hdGhzL2FsZ2VicmEvcmVhbE5vcm1lZEFsZ2VicmEvcXVhdGVybmlvbnMvY29kZS9pbmRleC5odG1cblxuXHRcdHZhciBxYXggPSBhLl94LCBxYXkgPSBhLl95LCBxYXogPSBhLl96LCBxYXcgPSBhLl93O1xuXHRcdHZhciBxYnggPSBiLl94LCBxYnkgPSBiLl95LCBxYnogPSBiLl96LCBxYncgPSBiLl93O1xuXG5cdFx0dGhpcy5feCA9IHFheCAqIHFidyArIHFhdyAqIHFieCArIHFheSAqIHFieiAtIHFheiAqIHFieTtcblx0XHR0aGlzLl95ID0gcWF5ICogcWJ3ICsgcWF3ICogcWJ5ICsgcWF6ICogcWJ4IC0gcWF4ICogcWJ6O1xuXHRcdHRoaXMuX3ogPSBxYXogKiBxYncgKyBxYXcgKiBxYnogKyBxYXggKiBxYnkgLSBxYXkgKiBxYng7XG5cdFx0dGhpcy5fdyA9IHFhdyAqIHFidyAtIHFheCAqIHFieCAtIHFheSAqIHFieSAtIHFheiAqIHFiejtcblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzbGVycDogZnVuY3Rpb24gKCBxYiwgdCApIHtcblxuXHRcdGlmICggdCA9PT0gMCApIHJldHVybiB0aGlzO1xuXHRcdGlmICggdCA9PT0gMSApIHJldHVybiB0aGlzLmNvcHkoIHFiICk7XG5cblx0XHR2YXIgeCA9IHRoaXMuX3gsIHkgPSB0aGlzLl95LCB6ID0gdGhpcy5feiwgdyA9IHRoaXMuX3c7XG5cblx0XHQvLyBodHRwOi8vd3d3LmV1Y2xpZGVhbnNwYWNlLmNvbS9tYXRocy9hbGdlYnJhL3JlYWxOb3JtZWRBbGdlYnJhL3F1YXRlcm5pb25zL3NsZXJwL1xuXG5cdFx0dmFyIGNvc0hhbGZUaGV0YSA9IHcgKiBxYi5fdyArIHggKiBxYi5feCArIHkgKiBxYi5feSArIHogKiBxYi5fejtcblxuXHRcdGlmICggY29zSGFsZlRoZXRhIDwgMCApIHtcblxuXHRcdFx0dGhpcy5fdyA9IC0gcWIuX3c7XG5cdFx0XHR0aGlzLl94ID0gLSBxYi5feDtcblx0XHRcdHRoaXMuX3kgPSAtIHFiLl95O1xuXHRcdFx0dGhpcy5feiA9IC0gcWIuX3o7XG5cblx0XHRcdGNvc0hhbGZUaGV0YSA9IC0gY29zSGFsZlRoZXRhO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dGhpcy5jb3B5KCBxYiApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBjb3NIYWxmVGhldGEgPj0gMS4wICkge1xuXG5cdFx0XHR0aGlzLl93ID0gdztcblx0XHRcdHRoaXMuX3ggPSB4O1xuXHRcdFx0dGhpcy5feSA9IHk7XG5cdFx0XHR0aGlzLl96ID0gejtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9XG5cblx0XHR2YXIgc2luSGFsZlRoZXRhID0gTWF0aC5zcXJ0KCAxLjAgLSBjb3NIYWxmVGhldGEgKiBjb3NIYWxmVGhldGEgKTtcblxuXHRcdGlmICggTWF0aC5hYnMoIHNpbkhhbGZUaGV0YSApIDwgMC4wMDEgKSB7XG5cblx0XHRcdHRoaXMuX3cgPSAwLjUgKiAoIHcgKyB0aGlzLl93ICk7XG5cdFx0XHR0aGlzLl94ID0gMC41ICogKCB4ICsgdGhpcy5feCApO1xuXHRcdFx0dGhpcy5feSA9IDAuNSAqICggeSArIHRoaXMuX3kgKTtcblx0XHRcdHRoaXMuX3ogPSAwLjUgKiAoIHogKyB0aGlzLl96ICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fVxuXG5cdFx0dmFyIGhhbGZUaGV0YSA9IE1hdGguYXRhbjIoIHNpbkhhbGZUaGV0YSwgY29zSGFsZlRoZXRhICk7XG5cdFx0dmFyIHJhdGlvQSA9IE1hdGguc2luKCAoIDEgLSB0ICkgKiBoYWxmVGhldGEgKSAvIHNpbkhhbGZUaGV0YSxcblx0XHRcdHJhdGlvQiA9IE1hdGguc2luKCB0ICogaGFsZlRoZXRhICkgLyBzaW5IYWxmVGhldGE7XG5cblx0XHR0aGlzLl93ID0gKCB3ICogcmF0aW9BICsgdGhpcy5fdyAqIHJhdGlvQiApO1xuXHRcdHRoaXMuX3ggPSAoIHggKiByYXRpb0EgKyB0aGlzLl94ICogcmF0aW9CICk7XG5cdFx0dGhpcy5feSA9ICggeSAqIHJhdGlvQSArIHRoaXMuX3kgKiByYXRpb0IgKTtcblx0XHR0aGlzLl96ID0gKCB6ICogcmF0aW9BICsgdGhpcy5feiAqIHJhdGlvQiApO1xuXG5cdFx0dGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGVxdWFsczogZnVuY3Rpb24gKCBxdWF0ZXJuaW9uICkge1xuXG5cdFx0cmV0dXJuICggcXVhdGVybmlvbi5feCA9PT0gdGhpcy5feCApICYmICggcXVhdGVybmlvbi5feSA9PT0gdGhpcy5feSApICYmICggcXVhdGVybmlvbi5feiA9PT0gdGhpcy5feiApICYmICggcXVhdGVybmlvbi5fdyA9PT0gdGhpcy5fdyApO1xuXG5cdH0sXG5cblx0ZnJvbUFycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHRoaXMuX3ggPSBhcnJheVsgb2Zmc2V0IF07XG5cdFx0dGhpcy5feSA9IGFycmF5WyBvZmZzZXQgKyAxIF07XG5cdFx0dGhpcy5feiA9IGFycmF5WyBvZmZzZXQgKyAyIF07XG5cdFx0dGhpcy5fdyA9IGFycmF5WyBvZmZzZXQgKyAzIF07XG5cblx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0dG9BcnJheTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBhcnJheSA9PT0gdW5kZWZpbmVkICkgYXJyYXkgPSBbXTtcblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdGFycmF5WyBvZmZzZXQgXSA9IHRoaXMuX3g7XG5cdFx0YXJyYXlbIG9mZnNldCArIDEgXSA9IHRoaXMuX3k7XG5cdFx0YXJyYXlbIG9mZnNldCArIDIgXSA9IHRoaXMuX3o7XG5cdFx0YXJyYXlbIG9mZnNldCArIDMgXSA9IHRoaXMuX3c7XG5cblx0XHRyZXR1cm4gYXJyYXk7XG5cblx0fSxcblxuXHRvbkNoYW5nZTogZnVuY3Rpb24gKCBjYWxsYmFjayApIHtcblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRvbkNoYW5nZUNhbGxiYWNrOiBmdW5jdGlvbiAoKSB7fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgKmtpbGUgLyBodHRwOi8va2lsZS5zdHJhdmFnYW56YS5vcmcvXG4gKiBAYXV0aG9yIHBoaWxvZ2IgLyBodHRwOi8vYmxvZy50aGVqaXQub3JnL1xuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgZWdyYWV0aGVyIC8gaHR0cDovL2VncmFldGhlci5jb20vXG4gKiBAYXV0aG9yIFdlc3RMYW5nbGV5IC8gaHR0cDovL2dpdGh1Yi5jb20vV2VzdExhbmdsZXlcbiAqL1xuXG5mdW5jdGlvbiBWZWN0b3IzKCB4LCB5LCB6ICkge1xuXG5cdHRoaXMueCA9IHggfHwgMDtcblx0dGhpcy55ID0geSB8fCAwO1xuXHR0aGlzLnogPSB6IHx8IDA7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggVmVjdG9yMy5wcm90b3R5cGUsIHtcblxuXHRpc1ZlY3RvcjM6IHRydWUsXG5cblx0c2V0OiBmdW5jdGlvbiAoIHgsIHksIHogKSB7XG5cblx0XHR0aGlzLnggPSB4O1xuXHRcdHRoaXMueSA9IHk7XG5cdFx0dGhpcy56ID0gejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHRoaXMueCA9IHNjYWxhcjtcblx0XHR0aGlzLnkgPSBzY2FsYXI7XG5cdFx0dGhpcy56ID0gc2NhbGFyO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRYOiBmdW5jdGlvbiAoIHggKSB7XG5cblx0XHR0aGlzLnggPSB4O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRZOiBmdW5jdGlvbiAoIHkgKSB7XG5cblx0XHR0aGlzLnkgPSB5O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRaOiBmdW5jdGlvbiAoIHogKSB7XG5cblx0XHR0aGlzLnogPSB6O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRDb21wb25lbnQ6IGZ1bmN0aW9uICggaW5kZXgsIHZhbHVlICkge1xuXG5cdFx0c3dpdGNoICggaW5kZXggKSB7XG5cblx0XHRcdGNhc2UgMDogdGhpcy54ID0gdmFsdWU7IGJyZWFrO1xuXHRcdFx0Y2FzZSAxOiB0aGlzLnkgPSB2YWx1ZTsgYnJlYWs7XG5cdFx0XHRjYXNlIDI6IHRoaXMueiA9IHZhbHVlOyBicmVhaztcblx0XHRcdGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvciggJ2luZGV4IGlzIG91dCBvZiByYW5nZTogJyArIGluZGV4ICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldENvbXBvbmVudDogZnVuY3Rpb24gKCBpbmRleCApIHtcblxuXHRcdHN3aXRjaCAoIGluZGV4ICkge1xuXG5cdFx0XHRjYXNlIDA6IHJldHVybiB0aGlzLng7XG5cdFx0XHRjYXNlIDE6IHJldHVybiB0aGlzLnk7XG5cdFx0XHRjYXNlIDI6IHJldHVybiB0aGlzLno7XG5cdFx0XHRkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoICdpbmRleCBpcyBvdXQgb2YgcmFuZ2U6ICcgKyBpbmRleCApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvciggdGhpcy54LCB0aGlzLnksIHRoaXMueiApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0dGhpcy54ID0gdi54O1xuXHRcdHRoaXMueSA9IHYueTtcblx0XHR0aGlzLnogPSB2Lno7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjM6IC5hZGQoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5hZGRWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5hZGRWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggKz0gdi54O1xuXHRcdHRoaXMueSArPSB2Lnk7XG5cdFx0dGhpcy56ICs9IHYuejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YWRkU2NhbGFyOiBmdW5jdGlvbiAoIHMgKSB7XG5cblx0XHR0aGlzLnggKz0gcztcblx0XHR0aGlzLnkgKz0gcztcblx0XHR0aGlzLnogKz0gcztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YWRkVmVjdG9yczogZnVuY3Rpb24gKCBhLCBiICkge1xuXG5cdFx0dGhpcy54ID0gYS54ICsgYi54O1xuXHRcdHRoaXMueSA9IGEueSArIGIueTtcblx0XHR0aGlzLnogPSBhLnogKyBiLno7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZFNjYWxlZFZlY3RvcjogZnVuY3Rpb24gKCB2LCBzICkge1xuXG5cdFx0dGhpcy54ICs9IHYueCAqIHM7XG5cdFx0dGhpcy55ICs9IHYueSAqIHM7XG5cdFx0dGhpcy56ICs9IHYueiAqIHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHN1YjogZnVuY3Rpb24gKCB2LCB3ICkge1xuXG5cdFx0aWYgKCB3ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjM6IC5zdWIoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5zdWJWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5zdWJWZWN0b3JzKCB2LCB3ICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnggLT0gdi54O1xuXHRcdHRoaXMueSAtPSB2Lnk7XG5cdFx0dGhpcy56IC09IHYuejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c3ViU2NhbGFyOiBmdW5jdGlvbiAoIHMgKSB7XG5cblx0XHR0aGlzLnggLT0gcztcblx0XHR0aGlzLnkgLT0gcztcblx0XHR0aGlzLnogLT0gcztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c3ViVmVjdG9yczogZnVuY3Rpb24gKCBhLCBiICkge1xuXG5cdFx0dGhpcy54ID0gYS54IC0gYi54O1xuXHRcdHRoaXMueSA9IGEueSAtIGIueTtcblx0XHR0aGlzLnogPSBhLnogLSBiLno7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG11bHRpcGx5OiBmdW5jdGlvbiAoIHYsIHcgKSB7XG5cblx0XHRpZiAoIHcgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVmVjdG9yMzogLm11bHRpcGx5KCkgbm93IG9ubHkgYWNjZXB0cyBvbmUgYXJndW1lbnQuIFVzZSAubXVsdGlwbHlWZWN0b3JzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVZlY3RvcnMoIHYsIHcgKTtcblxuXHRcdH1cblxuXHRcdHRoaXMueCAqPSB2Lng7XG5cdFx0dGhpcy55ICo9IHYueTtcblx0XHR0aGlzLnogKj0gdi56O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtdWx0aXBseVNjYWxhcjogZnVuY3Rpb24gKCBzY2FsYXIgKSB7XG5cblx0XHR0aGlzLnggKj0gc2NhbGFyO1xuXHRcdHRoaXMueSAqPSBzY2FsYXI7XG5cdFx0dGhpcy56ICo9IHNjYWxhcjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bXVsdGlwbHlWZWN0b3JzOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG5cblx0XHR0aGlzLnggPSBhLnggKiBiLng7XG5cdFx0dGhpcy55ID0gYS55ICogYi55O1xuXHRcdHRoaXMueiA9IGEueiAqIGIuejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YXBwbHlFdWxlcjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGFwcGx5RXVsZXIoIGV1bGVyICkge1xuXG5cdFx0XHRpZiAoICggZXVsZXIgJiYgZXVsZXIuaXNFdWxlciApID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuVmVjdG9yMzogLmFwcGx5RXVsZXIoKSBub3cgZXhwZWN0cyBhbiBFdWxlciByb3RhdGlvbiByYXRoZXIgdGhhbiBhIFZlY3RvcjMgYW5kIG9yZGVyLicgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdGhpcy5hcHBseVF1YXRlcm5pb24oIHF1YXRlcm5pb24uc2V0RnJvbUV1bGVyKCBldWxlciApICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRhcHBseUF4aXNBbmdsZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGFwcGx5QXhpc0FuZ2xlKCBheGlzLCBhbmdsZSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuYXBwbHlRdWF0ZXJuaW9uKCBxdWF0ZXJuaW9uLnNldEZyb21BeGlzQW5nbGUoIGF4aXMsIGFuZ2xlICkgKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGFwcGx5TWF0cml4MzogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLno7XG5cdFx0dmFyIGUgPSBtLmVsZW1lbnRzO1xuXG5cdFx0dGhpcy54ID0gZVsgMCBdICogeCArIGVbIDMgXSAqIHkgKyBlWyA2IF0gKiB6O1xuXHRcdHRoaXMueSA9IGVbIDEgXSAqIHggKyBlWyA0IF0gKiB5ICsgZVsgNyBdICogejtcblx0XHR0aGlzLnogPSBlWyAyIF0gKiB4ICsgZVsgNSBdICogeSArIGVbIDggXSAqIHo7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFwcGx5TWF0cml4NDogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLno7XG5cdFx0dmFyIGUgPSBtLmVsZW1lbnRzO1xuXG5cdFx0dGhpcy54ID0gZVsgMCBdICogeCArIGVbIDQgXSAqIHkgKyBlWyA4IF0gICogeiArIGVbIDEyIF07XG5cdFx0dGhpcy55ID0gZVsgMSBdICogeCArIGVbIDUgXSAqIHkgKyBlWyA5IF0gICogeiArIGVbIDEzIF07XG5cdFx0dGhpcy56ID0gZVsgMiBdICogeCArIGVbIDYgXSAqIHkgKyBlWyAxMCBdICogeiArIGVbIDE0IF07XG5cdFx0dmFyIHcgPSAgZVsgMyBdICogeCArIGVbIDcgXSAqIHkgKyBlWyAxMSBdICogeiArIGVbIDE1IF07XG5cblx0XHRyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIoIHcgKTtcblxuXHR9LFxuXG5cdGFwcGx5UXVhdGVybmlvbjogZnVuY3Rpb24gKCBxICkge1xuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLno7XG5cdFx0dmFyIHF4ID0gcS54LCBxeSA9IHEueSwgcXogPSBxLnosIHF3ID0gcS53O1xuXG5cdFx0Ly8gY2FsY3VsYXRlIHF1YXQgKiB2ZWN0b3JcblxuXHRcdHZhciBpeCA9ICBxdyAqIHggKyBxeSAqIHogLSBxeiAqIHk7XG5cdFx0dmFyIGl5ID0gIHF3ICogeSArIHF6ICogeCAtIHF4ICogejtcblx0XHR2YXIgaXogPSAgcXcgKiB6ICsgcXggKiB5IC0gcXkgKiB4O1xuXHRcdHZhciBpdyA9IC0gcXggKiB4IC0gcXkgKiB5IC0gcXogKiB6O1xuXG5cdFx0Ly8gY2FsY3VsYXRlIHJlc3VsdCAqIGludmVyc2UgcXVhdFxuXG5cdFx0dGhpcy54ID0gaXggKiBxdyArIGl3ICogLSBxeCArIGl5ICogLSBxeiAtIGl6ICogLSBxeTtcblx0XHR0aGlzLnkgPSBpeSAqIHF3ICsgaXcgKiAtIHF5ICsgaXogKiAtIHF4IC0gaXggKiAtIHF6O1xuXHRcdHRoaXMueiA9IGl6ICogcXcgKyBpdyAqIC0gcXogKyBpeCAqIC0gcXkgLSBpeSAqIC0gcXg7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHByb2plY3Q6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBtYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHByb2plY3QoIGNhbWVyYSApIHtcblxuXHRcdFx0bWF0cml4Lm11bHRpcGx5TWF0cmljZXMoIGNhbWVyYS5wcm9qZWN0aW9uTWF0cml4LCBtYXRyaXguZ2V0SW52ZXJzZSggY2FtZXJhLm1hdHJpeFdvcmxkICkgKTtcblx0XHRcdHJldHVybiB0aGlzLmFwcGx5TWF0cml4NCggbWF0cml4ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHR1bnByb2plY3Q6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBtYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHVucHJvamVjdCggY2FtZXJhICkge1xuXG5cdFx0XHRtYXRyaXgubXVsdGlwbHlNYXRyaWNlcyggY2FtZXJhLm1hdHJpeFdvcmxkLCBtYXRyaXguZ2V0SW52ZXJzZSggY2FtZXJhLnByb2plY3Rpb25NYXRyaXggKSApO1xuXHRcdFx0cmV0dXJuIHRoaXMuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdHRyYW5zZm9ybURpcmVjdGlvbjogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0Ly8gaW5wdXQ6IFRIUkVFLk1hdHJpeDQgYWZmaW5lIG1hdHJpeFxuXHRcdC8vIHZlY3RvciBpbnRlcnByZXRlZCBhcyBhIGRpcmVjdGlvblxuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLno7XG5cdFx0dmFyIGUgPSBtLmVsZW1lbnRzO1xuXG5cdFx0dGhpcy54ID0gZVsgMCBdICogeCArIGVbIDQgXSAqIHkgKyBlWyA4IF0gICogejtcblx0XHR0aGlzLnkgPSBlWyAxIF0gKiB4ICsgZVsgNSBdICogeSArIGVbIDkgXSAgKiB6O1xuXHRcdHRoaXMueiA9IGVbIDIgXSAqIHggKyBlWyA2IF0gKiB5ICsgZVsgMTAgXSAqIHo7XG5cblx0XHRyZXR1cm4gdGhpcy5ub3JtYWxpemUoKTtcblxuXHR9LFxuXG5cdGRpdmlkZTogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0dGhpcy54IC89IHYueDtcblx0XHR0aGlzLnkgLz0gdi55O1xuXHRcdHRoaXMueiAvPSB2Lno7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGRpdmlkZVNjYWxhcjogZnVuY3Rpb24gKCBzY2FsYXIgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVNjYWxhciggMSAvIHNjYWxhciApO1xuXG5cdH0sXG5cblx0bWluOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1pbiggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1pbiggdGhpcy55LCB2LnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLm1pbiggdGhpcy56LCB2LnogKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWF4OiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLm1heCggdGhpcy54LCB2LnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLm1heCggdGhpcy55LCB2LnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLm1heCggdGhpcy56LCB2LnogKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xhbXA6IGZ1bmN0aW9uICggbWluLCBtYXggKSB7XG5cblx0XHQvLyBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgbWluIDwgbWF4LCBpZiB0aGlzIGFzc3VtcHRpb24gaXNuJ3QgdHJ1ZSBpdCB3aWxsIG5vdCBvcGVyYXRlIGNvcnJlY3RseVxuXG5cdFx0dGhpcy54ID0gTWF0aC5tYXgoIG1pbi54LCBNYXRoLm1pbiggbWF4LngsIHRoaXMueCApICk7XG5cdFx0dGhpcy55ID0gTWF0aC5tYXgoIG1pbi55LCBNYXRoLm1pbiggbWF4LnksIHRoaXMueSApICk7XG5cdFx0dGhpcy56ID0gTWF0aC5tYXgoIG1pbi56LCBNYXRoLm1pbiggbWF4LnosIHRoaXMueiApICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsYW1wU2NhbGFyOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbWluID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgbWF4ID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBjbGFtcFNjYWxhciggbWluVmFsLCBtYXhWYWwgKSB7XG5cblx0XHRcdG1pbi5zZXQoIG1pblZhbCwgbWluVmFsLCBtaW5WYWwgKTtcblx0XHRcdG1heC5zZXQoIG1heFZhbCwgbWF4VmFsLCBtYXhWYWwgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXMuY2xhbXAoIG1pbiwgbWF4ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRjbGFtcExlbmd0aDogZnVuY3Rpb24gKCBtaW4sIG1heCApIHtcblxuXHRcdHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCgpO1xuXG5cdFx0cmV0dXJuIHRoaXMubXVsdGlwbHlTY2FsYXIoIE1hdGgubWF4KCBtaW4sIE1hdGgubWluKCBtYXgsIGxlbmd0aCApICkgLyBsZW5ndGggKTtcblxuXHR9LFxuXG5cdGZsb29yOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLmZsb29yKCB0aGlzLnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLmZsb29yKCB0aGlzLnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLmZsb29yKCB0aGlzLnogKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2VpbDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy54ID0gTWF0aC5jZWlsKCB0aGlzLnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLmNlaWwoIHRoaXMueSApO1xuXHRcdHRoaXMueiA9IE1hdGguY2VpbCggdGhpcy56ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHJvdW5kOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnggPSBNYXRoLnJvdW5kKCB0aGlzLnggKTtcblx0XHR0aGlzLnkgPSBNYXRoLnJvdW5kKCB0aGlzLnkgKTtcblx0XHR0aGlzLnogPSBNYXRoLnJvdW5kKCB0aGlzLnogKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0cm91bmRUb1plcm86IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9ICggdGhpcy54IDwgMCApID8gTWF0aC5jZWlsKCB0aGlzLnggKSA6IE1hdGguZmxvb3IoIHRoaXMueCApO1xuXHRcdHRoaXMueSA9ICggdGhpcy55IDwgMCApID8gTWF0aC5jZWlsKCB0aGlzLnkgKSA6IE1hdGguZmxvb3IoIHRoaXMueSApO1xuXHRcdHRoaXMueiA9ICggdGhpcy56IDwgMCApID8gTWF0aC5jZWlsKCB0aGlzLnogKSA6IE1hdGguZmxvb3IoIHRoaXMueiApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRuZWdhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMueCA9IC0gdGhpcy54O1xuXHRcdHRoaXMueSA9IC0gdGhpcy55O1xuXHRcdHRoaXMueiA9IC0gdGhpcy56O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRkb3Q6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHJldHVybiB0aGlzLnggKiB2LnggKyB0aGlzLnkgKiB2LnkgKyB0aGlzLnogKiB2Lno7XG5cblx0fSxcblxuXHQvLyBUT0RPIGxlbmd0aFNxdWFyZWQ/XG5cblx0bGVuZ3RoU3E6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnggKiB0aGlzLnggKyB0aGlzLnkgKiB0aGlzLnkgKyB0aGlzLnogKiB0aGlzLno7XG5cblx0fSxcblxuXHRsZW5ndGg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBNYXRoLnNxcnQoIHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueSArIHRoaXMueiAqIHRoaXMueiApO1xuXG5cdH0sXG5cblx0bGVuZ3RoTWFuaGF0dGFuOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gTWF0aC5hYnMoIHRoaXMueCApICsgTWF0aC5hYnMoIHRoaXMueSApICsgTWF0aC5hYnMoIHRoaXMueiApO1xuXG5cdH0sXG5cblx0bm9ybWFsaXplOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5kaXZpZGVTY2FsYXIoIHRoaXMubGVuZ3RoKCkgKTtcblxuXHR9LFxuXG5cdHNldExlbmd0aDogZnVuY3Rpb24gKCBsZW5ndGggKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseVNjYWxhciggbGVuZ3RoIC8gdGhpcy5sZW5ndGgoKSApO1xuXG5cdH0sXG5cblx0bGVycDogZnVuY3Rpb24gKCB2LCBhbHBoYSApIHtcblxuXHRcdHRoaXMueCArPSAoIHYueCAtIHRoaXMueCApICogYWxwaGE7XG5cdFx0dGhpcy55ICs9ICggdi55IC0gdGhpcy55ICkgKiBhbHBoYTtcblx0XHR0aGlzLnogKz0gKCB2LnogLSB0aGlzLnogKSAqIGFscGhhO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRsZXJwVmVjdG9yczogZnVuY3Rpb24gKCB2MSwgdjIsIGFscGhhICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuc3ViVmVjdG9ycyggdjIsIHYxICkubXVsdGlwbHlTY2FsYXIoIGFscGhhICkuYWRkKCB2MSApO1xuXG5cdH0sXG5cblx0Y3Jvc3M6IGZ1bmN0aW9uICggdiwgdyApIHtcblxuXHRcdGlmICggdyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5WZWN0b3IzOiAuY3Jvc3MoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5jcm9zc1ZlY3RvcnMoIGEsIGIgKSBpbnN0ZWFkLicgKTtcblx0XHRcdHJldHVybiB0aGlzLmNyb3NzVmVjdG9ycyggdiwgdyApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHggPSB0aGlzLngsIHkgPSB0aGlzLnksIHogPSB0aGlzLno7XG5cblx0XHR0aGlzLnggPSB5ICogdi56IC0geiAqIHYueTtcblx0XHR0aGlzLnkgPSB6ICogdi54IC0geCAqIHYuejtcblx0XHR0aGlzLnogPSB4ICogdi55IC0geSAqIHYueDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y3Jvc3NWZWN0b3JzOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG5cblx0XHR2YXIgYXggPSBhLngsIGF5ID0gYS55LCBheiA9IGEuejtcblx0XHR2YXIgYnggPSBiLngsIGJ5ID0gYi55LCBieiA9IGIuejtcblxuXHRcdHRoaXMueCA9IGF5ICogYnogLSBheiAqIGJ5O1xuXHRcdHRoaXMueSA9IGF6ICogYnggLSBheCAqIGJ6O1xuXHRcdHRoaXMueiA9IGF4ICogYnkgLSBheSAqIGJ4O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRwcm9qZWN0T25WZWN0b3I6IGZ1bmN0aW9uICggdmVjdG9yICkge1xuXG5cdFx0dmFyIHNjYWxhciA9IHZlY3Rvci5kb3QoIHRoaXMgKSAvIHZlY3Rvci5sZW5ndGhTcSgpO1xuXG5cdFx0cmV0dXJuIHRoaXMuY29weSggdmVjdG9yICkubXVsdGlwbHlTY2FsYXIoIHNjYWxhciApO1xuXG5cdH0sXG5cblx0cHJvamVjdE9uUGxhbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcHJvamVjdE9uUGxhbmUoIHBsYW5lTm9ybWFsICkge1xuXG5cdFx0XHR2MS5jb3B5KCB0aGlzICkucHJvamVjdE9uVmVjdG9yKCBwbGFuZU5vcm1hbCApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5zdWIoIHYxICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRyZWZsZWN0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyByZWZsZWN0IGluY2lkZW50IHZlY3RvciBvZmYgcGxhbmUgb3J0aG9nb25hbCB0byBub3JtYWxcblx0XHQvLyBub3JtYWwgaXMgYXNzdW1lZCB0byBoYXZlIHVuaXQgbGVuZ3RoXG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHJlZmxlY3QoIG5vcm1hbCApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuc3ViKCB2MS5jb3B5KCBub3JtYWwgKS5tdWx0aXBseVNjYWxhciggMiAqIHRoaXMuZG90KCBub3JtYWwgKSApICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRhbmdsZVRvOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHR2YXIgdGhldGEgPSB0aGlzLmRvdCggdiApIC8gKCBNYXRoLnNxcnQoIHRoaXMubGVuZ3RoU3EoKSAqIHYubGVuZ3RoU3EoKSApICk7XG5cblx0XHQvLyBjbGFtcCwgdG8gaGFuZGxlIG51bWVyaWNhbCBwcm9ibGVtc1xuXG5cdFx0cmV0dXJuIE1hdGguYWNvcyggX01hdGguY2xhbXAoIHRoZXRhLCAtIDEsIDEgKSApO1xuXG5cdH0sXG5cblx0ZGlzdGFuY2VUbzogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0cmV0dXJuIE1hdGguc3FydCggdGhpcy5kaXN0YW5jZVRvU3F1YXJlZCggdiApICk7XG5cblx0fSxcblxuXHRkaXN0YW5jZVRvU3F1YXJlZDogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0dmFyIGR4ID0gdGhpcy54IC0gdi54LCBkeSA9IHRoaXMueSAtIHYueSwgZHogPSB0aGlzLnogLSB2Lno7XG5cblx0XHRyZXR1cm4gZHggKiBkeCArIGR5ICogZHkgKyBkeiAqIGR6O1xuXG5cdH0sXG5cblx0ZGlzdGFuY2VUb01hbmhhdHRhbjogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0cmV0dXJuIE1hdGguYWJzKCB0aGlzLnggLSB2LnggKSArIE1hdGguYWJzKCB0aGlzLnkgLSB2LnkgKSArIE1hdGguYWJzKCB0aGlzLnogLSB2LnogKTtcblxuXHR9LFxuXG5cdHNldEZyb21TcGhlcmljYWw6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHZhciBzaW5QaGlSYWRpdXMgPSBNYXRoLnNpbiggcy5waGkgKSAqIHMucmFkaXVzO1xuXG5cdFx0dGhpcy54ID0gc2luUGhpUmFkaXVzICogTWF0aC5zaW4oIHMudGhldGEgKTtcblx0XHR0aGlzLnkgPSBNYXRoLmNvcyggcy5waGkgKSAqIHMucmFkaXVzO1xuXHRcdHRoaXMueiA9IHNpblBoaVJhZGl1cyAqIE1hdGguY29zKCBzLnRoZXRhICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21DeWxpbmRyaWNhbDogZnVuY3Rpb24gKCBjICkge1xuXG5cdFx0dGhpcy54ID0gYy5yYWRpdXMgKiBNYXRoLnNpbiggYy50aGV0YSApO1xuXHRcdHRoaXMueSA9IGMueTtcblx0XHR0aGlzLnogPSBjLnJhZGl1cyAqIE1hdGguY29zKCBjLnRoZXRhICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21NYXRyaXhQb3NpdGlvbjogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuc2V0RnJvbU1hdHJpeENvbHVtbiggbSwgMyApO1xuXG5cdH0sXG5cblx0c2V0RnJvbU1hdHJpeFNjYWxlOiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHR2YXIgc3ggPSB0aGlzLnNldEZyb21NYXRyaXhDb2x1bW4oIG0sIDAgKS5sZW5ndGgoKTtcblx0XHR2YXIgc3kgPSB0aGlzLnNldEZyb21NYXRyaXhDb2x1bW4oIG0sIDEgKS5sZW5ndGgoKTtcblx0XHR2YXIgc3ogPSB0aGlzLnNldEZyb21NYXRyaXhDb2x1bW4oIG0sIDIgKS5sZW5ndGgoKTtcblxuXHRcdHRoaXMueCA9IHN4O1xuXHRcdHRoaXMueSA9IHN5O1xuXHRcdHRoaXMueiA9IHN6O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tTWF0cml4Q29sdW1uOiBmdW5jdGlvbiAoIG0sIGluZGV4ICkge1xuXG5cblx0XHRyZXR1cm4gdGhpcy5mcm9tQXJyYXkoIG0uZWxlbWVudHMsIGluZGV4ICogNCApO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIHYgKSB7XG5cblx0XHRyZXR1cm4gKCAoIHYueCA9PT0gdGhpcy54ICkgJiYgKCB2LnkgPT09IHRoaXMueSApICYmICggdi56ID09PSB0aGlzLnogKSApO1xuXG5cdH0sXG5cblx0ZnJvbUFycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHRoaXMueCA9IGFycmF5WyBvZmZzZXQgXTtcblx0XHR0aGlzLnkgPSBhcnJheVsgb2Zmc2V0ICsgMSBdO1xuXHRcdHRoaXMueiA9IGFycmF5WyBvZmZzZXQgKyAyIF07XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uICggYXJyYXksIG9mZnNldCApIHtcblxuXHRcdGlmICggYXJyYXkgPT09IHVuZGVmaW5lZCApIGFycmF5ID0gW107XG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIG9mZnNldCA9IDA7XG5cblx0XHRhcnJheVsgb2Zmc2V0IF0gPSB0aGlzLng7XG5cdFx0YXJyYXlbIG9mZnNldCArIDEgXSA9IHRoaXMueTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMiBdID0gdGhpcy56O1xuXG5cdFx0cmV0dXJuIGFycmF5O1xuXG5cdH0sXG5cblx0ZnJvbUJ1ZmZlckF0dHJpYnV0ZTogZnVuY3Rpb24gKCBhdHRyaWJ1dGUsIGluZGV4LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5WZWN0b3IzOiBvZmZzZXQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIC5mcm9tQnVmZmVyQXR0cmlidXRlKCkuJyApO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy54ID0gYXR0cmlidXRlLmdldFgoIGluZGV4ICk7XG5cdFx0dGhpcy55ID0gYXR0cmlidXRlLmdldFkoIGluZGV4ICk7XG5cdFx0dGhpcy56ID0gYXR0cmlidXRlLmdldFooIGluZGV4ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBzdXBlcmVnZ2JlcnQgLyBodHRwOi8vd3d3LnBhdWxicnVudC5jby51ay9cbiAqIEBhdXRob3IgcGhpbG9nYiAvIGh0dHA6Ly9ibG9nLnRoZWppdC5vcmcvXG4gKiBAYXV0aG9yIGpvcmRpX3JvcyAvIGh0dHA6Ly9wbGF0dHNvZnQuY29tXG4gKiBAYXV0aG9yIEQxcGxvMWQgLyBodHRwOi8vZ2l0aHViLmNvbS9EMXBsbzFkXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgdGlta25pcCAvIGh0dHA6Ly93d3cuZmxvb3JwbGFubmVyLmNvbS9cbiAqIEBhdXRob3IgYmhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICovXG5cbmZ1bmN0aW9uIE1hdHJpeDQoKSB7XG5cblx0dGhpcy5lbGVtZW50cyA9IFtcblxuXHRcdDEsIDAsIDAsIDAsXG5cdFx0MCwgMSwgMCwgMCxcblx0XHQwLCAwLCAxLCAwLFxuXHRcdDAsIDAsIDAsIDFcblxuXHRdO1xuXG5cdGlmICggYXJndW1lbnRzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuTWF0cml4NDogdGhlIGNvbnN0cnVjdG9yIG5vIGxvbmdlciByZWFkcyBhcmd1bWVudHMuIHVzZSAuc2V0KCkgaW5zdGVhZC4nICk7XG5cblx0fVxuXG59XG5cbk9iamVjdC5hc3NpZ24oIE1hdHJpeDQucHJvdG90eXBlLCB7XG5cblx0aXNNYXRyaXg0OiB0cnVlLFxuXG5cdHNldDogZnVuY3Rpb24gKCBuMTEsIG4xMiwgbjEzLCBuMTQsIG4yMSwgbjIyLCBuMjMsIG4yNCwgbjMxLCBuMzIsIG4zMywgbjM0LCBuNDEsIG40MiwgbjQzLCBuNDQgKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0dGVbIDAgXSA9IG4xMTsgdGVbIDQgXSA9IG4xMjsgdGVbIDggXSA9IG4xMzsgdGVbIDEyIF0gPSBuMTQ7XG5cdFx0dGVbIDEgXSA9IG4yMTsgdGVbIDUgXSA9IG4yMjsgdGVbIDkgXSA9IG4yMzsgdGVbIDEzIF0gPSBuMjQ7XG5cdFx0dGVbIDIgXSA9IG4zMTsgdGVbIDYgXSA9IG4zMjsgdGVbIDEwIF0gPSBuMzM7IHRlWyAxNCBdID0gbjM0O1xuXHRcdHRlWyAzIF0gPSBuNDE7IHRlWyA3IF0gPSBuNDI7IHRlWyAxMSBdID0gbjQzOyB0ZVsgMTUgXSA9IG40NDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0aWRlbnRpdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHQxLCAwLCAwLCAwLFxuXHRcdFx0MCwgMSwgMCwgMCxcblx0XHRcdDAsIDAsIDEsIDAsXG5cdFx0XHQwLCAwLCAwLCAxXG5cblx0XHQpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyBNYXRyaXg0KCkuZnJvbUFycmF5KCB0aGlzLmVsZW1lbnRzICk7XG5cblx0fSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdHZhciBtZSA9IG0uZWxlbWVudHM7XG5cblx0XHR0ZVsgMCBdID0gbWVbIDAgXTsgdGVbIDEgXSA9IG1lWyAxIF07IHRlWyAyIF0gPSBtZVsgMiBdOyB0ZVsgMyBdID0gbWVbIDMgXTtcblx0XHR0ZVsgNCBdID0gbWVbIDQgXTsgdGVbIDUgXSA9IG1lWyA1IF07IHRlWyA2IF0gPSBtZVsgNiBdOyB0ZVsgNyBdID0gbWVbIDcgXTtcblx0XHR0ZVsgOCBdID0gbWVbIDggXTsgdGVbIDkgXSA9IG1lWyA5IF07IHRlWyAxMCBdID0gbWVbIDEwIF07IHRlWyAxMSBdID0gbWVbIDExIF07XG5cdFx0dGVbIDEyIF0gPSBtZVsgMTIgXTsgdGVbIDEzIF0gPSBtZVsgMTMgXTsgdGVbIDE0IF0gPSBtZVsgMTQgXTsgdGVbIDE1IF0gPSBtZVsgMTUgXTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weVBvc2l0aW9uOiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzLCBtZSA9IG0uZWxlbWVudHM7XG5cblx0XHR0ZVsgMTIgXSA9IG1lWyAxMiBdO1xuXHRcdHRlWyAxMyBdID0gbWVbIDEzIF07XG5cdFx0dGVbIDE0IF0gPSBtZVsgMTQgXTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXh0cmFjdEJhc2lzOiBmdW5jdGlvbiAoIHhBeGlzLCB5QXhpcywgekF4aXMgKSB7XG5cblx0XHR4QXhpcy5zZXRGcm9tTWF0cml4Q29sdW1uKCB0aGlzLCAwICk7XG5cdFx0eUF4aXMuc2V0RnJvbU1hdHJpeENvbHVtbiggdGhpcywgMSApO1xuXHRcdHpBeGlzLnNldEZyb21NYXRyaXhDb2x1bW4oIHRoaXMsIDIgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWFrZUJhc2lzOiBmdW5jdGlvbiAoIHhBeGlzLCB5QXhpcywgekF4aXMgKSB7XG5cblx0XHR0aGlzLnNldChcblx0XHRcdHhBeGlzLngsIHlBeGlzLngsIHpBeGlzLngsIDAsXG5cdFx0XHR4QXhpcy55LCB5QXhpcy55LCB6QXhpcy55LCAwLFxuXHRcdFx0eEF4aXMueiwgeUF4aXMueiwgekF4aXMueiwgMCxcblx0XHRcdDAsICAgICAgIDAsICAgICAgIDAsICAgICAgIDFcblx0XHQpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRleHRyYWN0Um90YXRpb246IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZXh0cmFjdFJvdGF0aW9uKCBtICkge1xuXG5cdFx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdFx0dmFyIG1lID0gbS5lbGVtZW50cztcblxuXHRcdFx0dmFyIHNjYWxlWCA9IDEgLyB2MS5zZXRGcm9tTWF0cml4Q29sdW1uKCBtLCAwICkubGVuZ3RoKCk7XG5cdFx0XHR2YXIgc2NhbGVZID0gMSAvIHYxLnNldEZyb21NYXRyaXhDb2x1bW4oIG0sIDEgKS5sZW5ndGgoKTtcblx0XHRcdHZhciBzY2FsZVogPSAxIC8gdjEuc2V0RnJvbU1hdHJpeENvbHVtbiggbSwgMiApLmxlbmd0aCgpO1xuXG5cdFx0XHR0ZVsgMCBdID0gbWVbIDAgXSAqIHNjYWxlWDtcblx0XHRcdHRlWyAxIF0gPSBtZVsgMSBdICogc2NhbGVYO1xuXHRcdFx0dGVbIDIgXSA9IG1lWyAyIF0gKiBzY2FsZVg7XG5cblx0XHRcdHRlWyA0IF0gPSBtZVsgNCBdICogc2NhbGVZO1xuXHRcdFx0dGVbIDUgXSA9IG1lWyA1IF0gKiBzY2FsZVk7XG5cdFx0XHR0ZVsgNiBdID0gbWVbIDYgXSAqIHNjYWxlWTtcblxuXHRcdFx0dGVbIDggXSA9IG1lWyA4IF0gKiBzY2FsZVo7XG5cdFx0XHR0ZVsgOSBdID0gbWVbIDkgXSAqIHNjYWxlWjtcblx0XHRcdHRlWyAxMCBdID0gbWVbIDEwIF0gKiBzY2FsZVo7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0bWFrZVJvdGF0aW9uRnJvbUV1bGVyOiBmdW5jdGlvbiAoIGV1bGVyICkge1xuXG5cdFx0aWYgKCAoIGV1bGVyICYmIGV1bGVyLmlzRXVsZXIgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5NYXRyaXg6IC5tYWtlUm90YXRpb25Gcm9tRXVsZXIoKSBub3cgZXhwZWN0cyBhIEV1bGVyIHJvdGF0aW9uIHJhdGhlciB0aGFuIGEgVmVjdG9yMyBhbmQgb3JkZXIuJyApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHRlID0gdGhpcy5lbGVtZW50cztcblxuXHRcdHZhciB4ID0gZXVsZXIueCwgeSA9IGV1bGVyLnksIHogPSBldWxlci56O1xuXHRcdHZhciBhID0gTWF0aC5jb3MoIHggKSwgYiA9IE1hdGguc2luKCB4ICk7XG5cdFx0dmFyIGMgPSBNYXRoLmNvcyggeSApLCBkID0gTWF0aC5zaW4oIHkgKTtcblx0XHR2YXIgZSA9IE1hdGguY29zKCB6ICksIGYgPSBNYXRoLnNpbiggeiApO1xuXG5cdFx0aWYgKCBldWxlci5vcmRlciA9PT0gJ1hZWicgKSB7XG5cblx0XHRcdHZhciBhZSA9IGEgKiBlLCBhZiA9IGEgKiBmLCBiZSA9IGIgKiBlLCBiZiA9IGIgKiBmO1xuXG5cdFx0XHR0ZVsgMCBdID0gYyAqIGU7XG5cdFx0XHR0ZVsgNCBdID0gLSBjICogZjtcblx0XHRcdHRlWyA4IF0gPSBkO1xuXG5cdFx0XHR0ZVsgMSBdID0gYWYgKyBiZSAqIGQ7XG5cdFx0XHR0ZVsgNSBdID0gYWUgLSBiZiAqIGQ7XG5cdFx0XHR0ZVsgOSBdID0gLSBiICogYztcblxuXHRcdFx0dGVbIDIgXSA9IGJmIC0gYWUgKiBkO1xuXHRcdFx0dGVbIDYgXSA9IGJlICsgYWYgKiBkO1xuXHRcdFx0dGVbIDEwIF0gPSBhICogYztcblxuXHRcdH0gZWxzZSBpZiAoIGV1bGVyLm9yZGVyID09PSAnWVhaJyApIHtcblxuXHRcdFx0dmFyIGNlID0gYyAqIGUsIGNmID0gYyAqIGYsIGRlID0gZCAqIGUsIGRmID0gZCAqIGY7XG5cblx0XHRcdHRlWyAwIF0gPSBjZSArIGRmICogYjtcblx0XHRcdHRlWyA0IF0gPSBkZSAqIGIgLSBjZjtcblx0XHRcdHRlWyA4IF0gPSBhICogZDtcblxuXHRcdFx0dGVbIDEgXSA9IGEgKiBmO1xuXHRcdFx0dGVbIDUgXSA9IGEgKiBlO1xuXHRcdFx0dGVbIDkgXSA9IC0gYjtcblxuXHRcdFx0dGVbIDIgXSA9IGNmICogYiAtIGRlO1xuXHRcdFx0dGVbIDYgXSA9IGRmICsgY2UgKiBiO1xuXHRcdFx0dGVbIDEwIF0gPSBhICogYztcblxuXHRcdH0gZWxzZSBpZiAoIGV1bGVyLm9yZGVyID09PSAnWlhZJyApIHtcblxuXHRcdFx0dmFyIGNlID0gYyAqIGUsIGNmID0gYyAqIGYsIGRlID0gZCAqIGUsIGRmID0gZCAqIGY7XG5cblx0XHRcdHRlWyAwIF0gPSBjZSAtIGRmICogYjtcblx0XHRcdHRlWyA0IF0gPSAtIGEgKiBmO1xuXHRcdFx0dGVbIDggXSA9IGRlICsgY2YgKiBiO1xuXG5cdFx0XHR0ZVsgMSBdID0gY2YgKyBkZSAqIGI7XG5cdFx0XHR0ZVsgNSBdID0gYSAqIGU7XG5cdFx0XHR0ZVsgOSBdID0gZGYgLSBjZSAqIGI7XG5cblx0XHRcdHRlWyAyIF0gPSAtIGEgKiBkO1xuXHRcdFx0dGVbIDYgXSA9IGI7XG5cdFx0XHR0ZVsgMTAgXSA9IGEgKiBjO1xuXG5cdFx0fSBlbHNlIGlmICggZXVsZXIub3JkZXIgPT09ICdaWVgnICkge1xuXG5cdFx0XHR2YXIgYWUgPSBhICogZSwgYWYgPSBhICogZiwgYmUgPSBiICogZSwgYmYgPSBiICogZjtcblxuXHRcdFx0dGVbIDAgXSA9IGMgKiBlO1xuXHRcdFx0dGVbIDQgXSA9IGJlICogZCAtIGFmO1xuXHRcdFx0dGVbIDggXSA9IGFlICogZCArIGJmO1xuXG5cdFx0XHR0ZVsgMSBdID0gYyAqIGY7XG5cdFx0XHR0ZVsgNSBdID0gYmYgKiBkICsgYWU7XG5cdFx0XHR0ZVsgOSBdID0gYWYgKiBkIC0gYmU7XG5cblx0XHRcdHRlWyAyIF0gPSAtIGQ7XG5cdFx0XHR0ZVsgNiBdID0gYiAqIGM7XG5cdFx0XHR0ZVsgMTAgXSA9IGEgKiBjO1xuXG5cdFx0fSBlbHNlIGlmICggZXVsZXIub3JkZXIgPT09ICdZWlgnICkge1xuXG5cdFx0XHR2YXIgYWMgPSBhICogYywgYWQgPSBhICogZCwgYmMgPSBiICogYywgYmQgPSBiICogZDtcblxuXHRcdFx0dGVbIDAgXSA9IGMgKiBlO1xuXHRcdFx0dGVbIDQgXSA9IGJkIC0gYWMgKiBmO1xuXHRcdFx0dGVbIDggXSA9IGJjICogZiArIGFkO1xuXG5cdFx0XHR0ZVsgMSBdID0gZjtcblx0XHRcdHRlWyA1IF0gPSBhICogZTtcblx0XHRcdHRlWyA5IF0gPSAtIGIgKiBlO1xuXG5cdFx0XHR0ZVsgMiBdID0gLSBkICogZTtcblx0XHRcdHRlWyA2IF0gPSBhZCAqIGYgKyBiYztcblx0XHRcdHRlWyAxMCBdID0gYWMgLSBiZCAqIGY7XG5cblx0XHR9IGVsc2UgaWYgKCBldWxlci5vcmRlciA9PT0gJ1haWScgKSB7XG5cblx0XHRcdHZhciBhYyA9IGEgKiBjLCBhZCA9IGEgKiBkLCBiYyA9IGIgKiBjLCBiZCA9IGIgKiBkO1xuXG5cdFx0XHR0ZVsgMCBdID0gYyAqIGU7XG5cdFx0XHR0ZVsgNCBdID0gLSBmO1xuXHRcdFx0dGVbIDggXSA9IGQgKiBlO1xuXG5cdFx0XHR0ZVsgMSBdID0gYWMgKiBmICsgYmQ7XG5cdFx0XHR0ZVsgNSBdID0gYSAqIGU7XG5cdFx0XHR0ZVsgOSBdID0gYWQgKiBmIC0gYmM7XG5cblx0XHRcdHRlWyAyIF0gPSBiYyAqIGYgLSBhZDtcblx0XHRcdHRlWyA2IF0gPSBiICogZTtcblx0XHRcdHRlWyAxMCBdID0gYmQgKiBmICsgYWM7XG5cblx0XHR9XG5cblx0XHQvLyBsYXN0IGNvbHVtblxuXHRcdHRlWyAzIF0gPSAwO1xuXHRcdHRlWyA3IF0gPSAwO1xuXHRcdHRlWyAxMSBdID0gMDtcblxuXHRcdC8vIGJvdHRvbSByb3dcblx0XHR0ZVsgMTIgXSA9IDA7XG5cdFx0dGVbIDEzIF0gPSAwO1xuXHRcdHRlWyAxNCBdID0gMDtcblx0XHR0ZVsgMTUgXSA9IDE7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uOiBmdW5jdGlvbiAoIHEgKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0dmFyIHggPSBxLl94LCB5ID0gcS5feSwgeiA9IHEuX3osIHcgPSBxLl93O1xuXHRcdHZhciB4MiA9IHggKyB4LCB5MiA9IHkgKyB5LCB6MiA9IHogKyB6O1xuXHRcdHZhciB4eCA9IHggKiB4MiwgeHkgPSB4ICogeTIsIHh6ID0geCAqIHoyO1xuXHRcdHZhciB5eSA9IHkgKiB5MiwgeXogPSB5ICogejIsIHp6ID0geiAqIHoyO1xuXHRcdHZhciB3eCA9IHcgKiB4Miwgd3kgPSB3ICogeTIsIHd6ID0gdyAqIHoyO1xuXG5cdFx0dGVbIDAgXSA9IDEgLSAoIHl5ICsgenogKTtcblx0XHR0ZVsgNCBdID0geHkgLSB3ejtcblx0XHR0ZVsgOCBdID0geHogKyB3eTtcblxuXHRcdHRlWyAxIF0gPSB4eSArIHd6O1xuXHRcdHRlWyA1IF0gPSAxIC0gKCB4eCArIHp6ICk7XG5cdFx0dGVbIDkgXSA9IHl6IC0gd3g7XG5cblx0XHR0ZVsgMiBdID0geHogLSB3eTtcblx0XHR0ZVsgNiBdID0geXogKyB3eDtcblx0XHR0ZVsgMTAgXSA9IDEgLSAoIHh4ICsgeXkgKTtcblxuXHRcdC8vIGxhc3QgY29sdW1uXG5cdFx0dGVbIDMgXSA9IDA7XG5cdFx0dGVbIDcgXSA9IDA7XG5cdFx0dGVbIDExIF0gPSAwO1xuXG5cdFx0Ly8gYm90dG9tIHJvd1xuXHRcdHRlWyAxMiBdID0gMDtcblx0XHR0ZVsgMTMgXSA9IDA7XG5cdFx0dGVbIDE0IF0gPSAwO1xuXHRcdHRlWyAxNSBdID0gMTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bG9va0F0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgeCA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIHkgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB6ID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBsb29rQXQoIGV5ZSwgdGFyZ2V0LCB1cCApIHtcblxuXHRcdFx0dmFyIHRlID0gdGhpcy5lbGVtZW50cztcblxuXHRcdFx0ei5zdWJWZWN0b3JzKCBleWUsIHRhcmdldCApO1xuXG5cdFx0XHRpZiAoIHoubGVuZ3RoU3EoKSA9PT0gMCApIHtcblxuXHRcdFx0XHQvLyBleWUgYW5kIHRhcmdldCBhcmUgaW4gdGhlIHNhbWUgcG9zaXRpb25cblxuXHRcdFx0XHR6LnogPSAxO1xuXG5cdFx0XHR9XG5cblx0XHRcdHoubm9ybWFsaXplKCk7XG5cdFx0XHR4LmNyb3NzVmVjdG9ycyggdXAsIHogKTtcblxuXHRcdFx0aWYgKCB4Lmxlbmd0aFNxKCkgPT09IDAgKSB7XG5cblx0XHRcdFx0Ly8gZXllIGFuZCB0YXJnZXQgYXJlIGluIHRoZSBzYW1lIHZlcnRpY2FsXG5cblx0XHRcdFx0ei56ICs9IDAuMDAwMTtcblx0XHRcdFx0eC5jcm9zc1ZlY3RvcnMoIHVwLCB6ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0eC5ub3JtYWxpemUoKTtcblx0XHRcdHkuY3Jvc3NWZWN0b3JzKCB6LCB4ICk7XG5cblx0XHRcdHRlWyAwIF0gPSB4Lng7IHRlWyA0IF0gPSB5Lng7IHRlWyA4IF0gPSB6Lng7XG5cdFx0XHR0ZVsgMSBdID0geC55OyB0ZVsgNSBdID0geS55OyB0ZVsgOSBdID0gei55O1xuXHRcdFx0dGVbIDIgXSA9IHguejsgdGVbIDYgXSA9IHkuejsgdGVbIDEwIF0gPSB6Lno7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0bXVsdGlwbHk6IGZ1bmN0aW9uICggbSwgbiApIHtcblxuXHRcdGlmICggbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRyaXg0OiAubXVsdGlwbHkoKSBub3cgb25seSBhY2NlcHRzIG9uZSBhcmd1bWVudC4gVXNlIC5tdWx0aXBseU1hdHJpY2VzKCBhLCBiICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKCBtLCBuICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5tdWx0aXBseU1hdHJpY2VzKCB0aGlzLCBtICk7XG5cblx0fSxcblxuXHRwcmVtdWx0aXBseTogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyggbSwgdGhpcyApO1xuXG5cdH0sXG5cblx0bXVsdGlwbHlNYXRyaWNlczogZnVuY3Rpb24gKCBhLCBiICkge1xuXG5cdFx0dmFyIGFlID0gYS5lbGVtZW50cztcblx0XHR2YXIgYmUgPSBiLmVsZW1lbnRzO1xuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR2YXIgYTExID0gYWVbIDAgXSwgYTEyID0gYWVbIDQgXSwgYTEzID0gYWVbIDggXSwgYTE0ID0gYWVbIDEyIF07XG5cdFx0dmFyIGEyMSA9IGFlWyAxIF0sIGEyMiA9IGFlWyA1IF0sIGEyMyA9IGFlWyA5IF0sIGEyNCA9IGFlWyAxMyBdO1xuXHRcdHZhciBhMzEgPSBhZVsgMiBdLCBhMzIgPSBhZVsgNiBdLCBhMzMgPSBhZVsgMTAgXSwgYTM0ID0gYWVbIDE0IF07XG5cdFx0dmFyIGE0MSA9IGFlWyAzIF0sIGE0MiA9IGFlWyA3IF0sIGE0MyA9IGFlWyAxMSBdLCBhNDQgPSBhZVsgMTUgXTtcblxuXHRcdHZhciBiMTEgPSBiZVsgMCBdLCBiMTIgPSBiZVsgNCBdLCBiMTMgPSBiZVsgOCBdLCBiMTQgPSBiZVsgMTIgXTtcblx0XHR2YXIgYjIxID0gYmVbIDEgXSwgYjIyID0gYmVbIDUgXSwgYjIzID0gYmVbIDkgXSwgYjI0ID0gYmVbIDEzIF07XG5cdFx0dmFyIGIzMSA9IGJlWyAyIF0sIGIzMiA9IGJlWyA2IF0sIGIzMyA9IGJlWyAxMCBdLCBiMzQgPSBiZVsgMTQgXTtcblx0XHR2YXIgYjQxID0gYmVbIDMgXSwgYjQyID0gYmVbIDcgXSwgYjQzID0gYmVbIDExIF0sIGI0NCA9IGJlWyAxNSBdO1xuXG5cdFx0dGVbIDAgXSA9IGExMSAqIGIxMSArIGExMiAqIGIyMSArIGExMyAqIGIzMSArIGExNCAqIGI0MTtcblx0XHR0ZVsgNCBdID0gYTExICogYjEyICsgYTEyICogYjIyICsgYTEzICogYjMyICsgYTE0ICogYjQyO1xuXHRcdHRlWyA4IF0gPSBhMTEgKiBiMTMgKyBhMTIgKiBiMjMgKyBhMTMgKiBiMzMgKyBhMTQgKiBiNDM7XG5cdFx0dGVbIDEyIF0gPSBhMTEgKiBiMTQgKyBhMTIgKiBiMjQgKyBhMTMgKiBiMzQgKyBhMTQgKiBiNDQ7XG5cblx0XHR0ZVsgMSBdID0gYTIxICogYjExICsgYTIyICogYjIxICsgYTIzICogYjMxICsgYTI0ICogYjQxO1xuXHRcdHRlWyA1IF0gPSBhMjEgKiBiMTIgKyBhMjIgKiBiMjIgKyBhMjMgKiBiMzIgKyBhMjQgKiBiNDI7XG5cdFx0dGVbIDkgXSA9IGEyMSAqIGIxMyArIGEyMiAqIGIyMyArIGEyMyAqIGIzMyArIGEyNCAqIGI0Mztcblx0XHR0ZVsgMTMgXSA9IGEyMSAqIGIxNCArIGEyMiAqIGIyNCArIGEyMyAqIGIzNCArIGEyNCAqIGI0NDtcblxuXHRcdHRlWyAyIF0gPSBhMzEgKiBiMTEgKyBhMzIgKiBiMjEgKyBhMzMgKiBiMzEgKyBhMzQgKiBiNDE7XG5cdFx0dGVbIDYgXSA9IGEzMSAqIGIxMiArIGEzMiAqIGIyMiArIGEzMyAqIGIzMiArIGEzNCAqIGI0Mjtcblx0XHR0ZVsgMTAgXSA9IGEzMSAqIGIxMyArIGEzMiAqIGIyMyArIGEzMyAqIGIzMyArIGEzNCAqIGI0Mztcblx0XHR0ZVsgMTQgXSA9IGEzMSAqIGIxNCArIGEzMiAqIGIyNCArIGEzMyAqIGIzNCArIGEzNCAqIGI0NDtcblxuXHRcdHRlWyAzIF0gPSBhNDEgKiBiMTEgKyBhNDIgKiBiMjEgKyBhNDMgKiBiMzEgKyBhNDQgKiBiNDE7XG5cdFx0dGVbIDcgXSA9IGE0MSAqIGIxMiArIGE0MiAqIGIyMiArIGE0MyAqIGIzMiArIGE0NCAqIGI0Mjtcblx0XHR0ZVsgMTEgXSA9IGE0MSAqIGIxMyArIGE0MiAqIGIyMyArIGE0MyAqIGIzMyArIGE0NCAqIGI0Mztcblx0XHR0ZVsgMTUgXSA9IGE0MSAqIGIxNCArIGE0MiAqIGIyNCArIGE0MyAqIGIzNCArIGE0NCAqIGI0NDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bXVsdGlwbHlTY2FsYXI6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR0ZVsgMCBdICo9IHM7IHRlWyA0IF0gKj0gczsgdGVbIDggXSAqPSBzOyB0ZVsgMTIgXSAqPSBzO1xuXHRcdHRlWyAxIF0gKj0gczsgdGVbIDUgXSAqPSBzOyB0ZVsgOSBdICo9IHM7IHRlWyAxMyBdICo9IHM7XG5cdFx0dGVbIDIgXSAqPSBzOyB0ZVsgNiBdICo9IHM7IHRlWyAxMCBdICo9IHM7IHRlWyAxNCBdICo9IHM7XG5cdFx0dGVbIDMgXSAqPSBzOyB0ZVsgNyBdICo9IHM7IHRlWyAxMSBdICo9IHM7IHRlWyAxNSBdICo9IHM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFwcGx5VG9CdWZmZXJBdHRyaWJ1dGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gYXBwbHlUb0J1ZmZlckF0dHJpYnV0ZSggYXR0cmlidXRlICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBhdHRyaWJ1dGUuY291bnQ7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdHYxLnggPSBhdHRyaWJ1dGUuZ2V0WCggaSApO1xuXHRcdFx0XHR2MS55ID0gYXR0cmlidXRlLmdldFkoIGkgKTtcblx0XHRcdFx0djEueiA9IGF0dHJpYnV0ZS5nZXRaKCBpICk7XG5cblx0XHRcdFx0djEuYXBwbHlNYXRyaXg0KCB0aGlzICk7XG5cblx0XHRcdFx0YXR0cmlidXRlLnNldFhZWiggaSwgdjEueCwgdjEueSwgdjEueiApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBhdHRyaWJ1dGU7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRkZXRlcm1pbmFudDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHRlID0gdGhpcy5lbGVtZW50cztcblxuXHRcdHZhciBuMTEgPSB0ZVsgMCBdLCBuMTIgPSB0ZVsgNCBdLCBuMTMgPSB0ZVsgOCBdLCBuMTQgPSB0ZVsgMTIgXTtcblx0XHR2YXIgbjIxID0gdGVbIDEgXSwgbjIyID0gdGVbIDUgXSwgbjIzID0gdGVbIDkgXSwgbjI0ID0gdGVbIDEzIF07XG5cdFx0dmFyIG4zMSA9IHRlWyAyIF0sIG4zMiA9IHRlWyA2IF0sIG4zMyA9IHRlWyAxMCBdLCBuMzQgPSB0ZVsgMTQgXTtcblx0XHR2YXIgbjQxID0gdGVbIDMgXSwgbjQyID0gdGVbIDcgXSwgbjQzID0gdGVbIDExIF0sIG40NCA9IHRlWyAxNSBdO1xuXG5cdFx0Ly9UT0RPOiBtYWtlIHRoaXMgbW9yZSBlZmZpY2llbnRcblx0XHQvLyggYmFzZWQgb24gaHR0cDovL3d3dy5ldWNsaWRlYW5zcGFjZS5jb20vbWF0aHMvYWxnZWJyYS9tYXRyaXgvZnVuY3Rpb25zL2ludmVyc2UvZm91ckQvaW5kZXguaHRtIClcblxuXHRcdHJldHVybiAoXG5cdFx0XHRuNDEgKiAoXG5cdFx0XHRcdCsgbjE0ICogbjIzICogbjMyXG5cdFx0XHRcdCAtIG4xMyAqIG4yNCAqIG4zMlxuXHRcdFx0XHQgLSBuMTQgKiBuMjIgKiBuMzNcblx0XHRcdFx0ICsgbjEyICogbjI0ICogbjMzXG5cdFx0XHRcdCArIG4xMyAqIG4yMiAqIG4zNFxuXHRcdFx0XHQgLSBuMTIgKiBuMjMgKiBuMzRcblx0XHRcdCkgK1xuXHRcdFx0bjQyICogKFxuXHRcdFx0XHQrIG4xMSAqIG4yMyAqIG4zNFxuXHRcdFx0XHQgLSBuMTEgKiBuMjQgKiBuMzNcblx0XHRcdFx0ICsgbjE0ICogbjIxICogbjMzXG5cdFx0XHRcdCAtIG4xMyAqIG4yMSAqIG4zNFxuXHRcdFx0XHQgKyBuMTMgKiBuMjQgKiBuMzFcblx0XHRcdFx0IC0gbjE0ICogbjIzICogbjMxXG5cdFx0XHQpICtcblx0XHRcdG40MyAqIChcblx0XHRcdFx0KyBuMTEgKiBuMjQgKiBuMzJcblx0XHRcdFx0IC0gbjExICogbjIyICogbjM0XG5cdFx0XHRcdCAtIG4xNCAqIG4yMSAqIG4zMlxuXHRcdFx0XHQgKyBuMTIgKiBuMjEgKiBuMzRcblx0XHRcdFx0ICsgbjE0ICogbjIyICogbjMxXG5cdFx0XHRcdCAtIG4xMiAqIG4yNCAqIG4zMVxuXHRcdFx0KSArXG5cdFx0XHRuNDQgKiAoXG5cdFx0XHRcdC0gbjEzICogbjIyICogbjMxXG5cdFx0XHRcdCAtIG4xMSAqIG4yMyAqIG4zMlxuXHRcdFx0XHQgKyBuMTEgKiBuMjIgKiBuMzNcblx0XHRcdFx0ICsgbjEzICogbjIxICogbjMyXG5cdFx0XHRcdCAtIG4xMiAqIG4yMSAqIG4zM1xuXHRcdFx0XHQgKyBuMTIgKiBuMjMgKiBuMzFcblx0XHRcdClcblxuXHRcdCk7XG5cblx0fSxcblxuXHR0cmFuc3Bvc2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cdFx0dmFyIHRtcDtcblxuXHRcdHRtcCA9IHRlWyAxIF07IHRlWyAxIF0gPSB0ZVsgNCBdOyB0ZVsgNCBdID0gdG1wO1xuXHRcdHRtcCA9IHRlWyAyIF07IHRlWyAyIF0gPSB0ZVsgOCBdOyB0ZVsgOCBdID0gdG1wO1xuXHRcdHRtcCA9IHRlWyA2IF07IHRlWyA2IF0gPSB0ZVsgOSBdOyB0ZVsgOSBdID0gdG1wO1xuXG5cdFx0dG1wID0gdGVbIDMgXTsgdGVbIDMgXSA9IHRlWyAxMiBdOyB0ZVsgMTIgXSA9IHRtcDtcblx0XHR0bXAgPSB0ZVsgNyBdOyB0ZVsgNyBdID0gdGVbIDEzIF07IHRlWyAxMyBdID0gdG1wO1xuXHRcdHRtcCA9IHRlWyAxMSBdOyB0ZVsgMTEgXSA9IHRlWyAxNCBdOyB0ZVsgMTQgXSA9IHRtcDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0UG9zaXRpb246IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR0ZVsgMTIgXSA9IHYueDtcblx0XHR0ZVsgMTMgXSA9IHYueTtcblx0XHR0ZVsgMTQgXSA9IHYuejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Z2V0SW52ZXJzZTogZnVuY3Rpb24gKCBtLCB0aHJvd09uRGVnZW5lcmF0ZSApIHtcblxuXHRcdC8vIGJhc2VkIG9uIGh0dHA6Ly93d3cuZXVjbGlkZWFuc3BhY2UuY29tL21hdGhzL2FsZ2VicmEvbWF0cml4L2Z1bmN0aW9ucy9pbnZlcnNlL2ZvdXJEL2luZGV4Lmh0bVxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHMsXG5cdFx0XHRtZSA9IG0uZWxlbWVudHMsXG5cblx0XHRcdG4xMSA9IG1lWyAwIF0sIG4yMSA9IG1lWyAxIF0sIG4zMSA9IG1lWyAyIF0sIG40MSA9IG1lWyAzIF0sXG5cdFx0XHRuMTIgPSBtZVsgNCBdLCBuMjIgPSBtZVsgNSBdLCBuMzIgPSBtZVsgNiBdLCBuNDIgPSBtZVsgNyBdLFxuXHRcdFx0bjEzID0gbWVbIDggXSwgbjIzID0gbWVbIDkgXSwgbjMzID0gbWVbIDEwIF0sIG40MyA9IG1lWyAxMSBdLFxuXHRcdFx0bjE0ID0gbWVbIDEyIF0sIG4yNCA9IG1lWyAxMyBdLCBuMzQgPSBtZVsgMTQgXSwgbjQ0ID0gbWVbIDE1IF0sXG5cblx0XHRcdHQxMSA9IG4yMyAqIG4zNCAqIG40MiAtIG4yNCAqIG4zMyAqIG40MiArIG4yNCAqIG4zMiAqIG40MyAtIG4yMiAqIG4zNCAqIG40MyAtIG4yMyAqIG4zMiAqIG40NCArIG4yMiAqIG4zMyAqIG40NCxcblx0XHRcdHQxMiA9IG4xNCAqIG4zMyAqIG40MiAtIG4xMyAqIG4zNCAqIG40MiAtIG4xNCAqIG4zMiAqIG40MyArIG4xMiAqIG4zNCAqIG40MyArIG4xMyAqIG4zMiAqIG40NCAtIG4xMiAqIG4zMyAqIG40NCxcblx0XHRcdHQxMyA9IG4xMyAqIG4yNCAqIG40MiAtIG4xNCAqIG4yMyAqIG40MiArIG4xNCAqIG4yMiAqIG40MyAtIG4xMiAqIG4yNCAqIG40MyAtIG4xMyAqIG4yMiAqIG40NCArIG4xMiAqIG4yMyAqIG40NCxcblx0XHRcdHQxNCA9IG4xNCAqIG4yMyAqIG4zMiAtIG4xMyAqIG4yNCAqIG4zMiAtIG4xNCAqIG4yMiAqIG4zMyArIG4xMiAqIG4yNCAqIG4zMyArIG4xMyAqIG4yMiAqIG4zNCAtIG4xMiAqIG4yMyAqIG4zNDtcblxuXHRcdHZhciBkZXQgPSBuMTEgKiB0MTEgKyBuMjEgKiB0MTIgKyBuMzEgKiB0MTMgKyBuNDEgKiB0MTQ7XG5cblx0XHRpZiAoIGRldCA9PT0gMCApIHtcblxuXHRcdFx0dmFyIG1zZyA9IFwiVEhSRUUuTWF0cml4NC5nZXRJbnZlcnNlKCk6IGNhbid0IGludmVydCBtYXRyaXgsIGRldGVybWluYW50IGlzIDBcIjtcblxuXHRcdFx0aWYgKCB0aHJvd09uRGVnZW5lcmF0ZSA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIG1zZyApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggbXNnICk7XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXMuaWRlbnRpdHkoKTtcblxuXHRcdH1cblxuXHRcdHZhciBkZXRJbnYgPSAxIC8gZGV0O1xuXG5cdFx0dGVbIDAgXSA9IHQxMSAqIGRldEludjtcblx0XHR0ZVsgMSBdID0gKCBuMjQgKiBuMzMgKiBuNDEgLSBuMjMgKiBuMzQgKiBuNDEgLSBuMjQgKiBuMzEgKiBuNDMgKyBuMjEgKiBuMzQgKiBuNDMgKyBuMjMgKiBuMzEgKiBuNDQgLSBuMjEgKiBuMzMgKiBuNDQgKSAqIGRldEludjtcblx0XHR0ZVsgMiBdID0gKCBuMjIgKiBuMzQgKiBuNDEgLSBuMjQgKiBuMzIgKiBuNDEgKyBuMjQgKiBuMzEgKiBuNDIgLSBuMjEgKiBuMzQgKiBuNDIgLSBuMjIgKiBuMzEgKiBuNDQgKyBuMjEgKiBuMzIgKiBuNDQgKSAqIGRldEludjtcblx0XHR0ZVsgMyBdID0gKCBuMjMgKiBuMzIgKiBuNDEgLSBuMjIgKiBuMzMgKiBuNDEgLSBuMjMgKiBuMzEgKiBuNDIgKyBuMjEgKiBuMzMgKiBuNDIgKyBuMjIgKiBuMzEgKiBuNDMgLSBuMjEgKiBuMzIgKiBuNDMgKSAqIGRldEludjtcblxuXHRcdHRlWyA0IF0gPSB0MTIgKiBkZXRJbnY7XG5cdFx0dGVbIDUgXSA9ICggbjEzICogbjM0ICogbjQxIC0gbjE0ICogbjMzICogbjQxICsgbjE0ICogbjMxICogbjQzIC0gbjExICogbjM0ICogbjQzIC0gbjEzICogbjMxICogbjQ0ICsgbjExICogbjMzICogbjQ0ICkgKiBkZXRJbnY7XG5cdFx0dGVbIDYgXSA9ICggbjE0ICogbjMyICogbjQxIC0gbjEyICogbjM0ICogbjQxIC0gbjE0ICogbjMxICogbjQyICsgbjExICogbjM0ICogbjQyICsgbjEyICogbjMxICogbjQ0IC0gbjExICogbjMyICogbjQ0ICkgKiBkZXRJbnY7XG5cdFx0dGVbIDcgXSA9ICggbjEyICogbjMzICogbjQxIC0gbjEzICogbjMyICogbjQxICsgbjEzICogbjMxICogbjQyIC0gbjExICogbjMzICogbjQyIC0gbjEyICogbjMxICogbjQzICsgbjExICogbjMyICogbjQzICkgKiBkZXRJbnY7XG5cblx0XHR0ZVsgOCBdID0gdDEzICogZGV0SW52O1xuXHRcdHRlWyA5IF0gPSAoIG4xNCAqIG4yMyAqIG40MSAtIG4xMyAqIG4yNCAqIG40MSAtIG4xNCAqIG4yMSAqIG40MyArIG4xMSAqIG4yNCAqIG40MyArIG4xMyAqIG4yMSAqIG40NCAtIG4xMSAqIG4yMyAqIG40NCApICogZGV0SW52O1xuXHRcdHRlWyAxMCBdID0gKCBuMTIgKiBuMjQgKiBuNDEgLSBuMTQgKiBuMjIgKiBuNDEgKyBuMTQgKiBuMjEgKiBuNDIgLSBuMTEgKiBuMjQgKiBuNDIgLSBuMTIgKiBuMjEgKiBuNDQgKyBuMTEgKiBuMjIgKiBuNDQgKSAqIGRldEludjtcblx0XHR0ZVsgMTEgXSA9ICggbjEzICogbjIyICogbjQxIC0gbjEyICogbjIzICogbjQxIC0gbjEzICogbjIxICogbjQyICsgbjExICogbjIzICogbjQyICsgbjEyICogbjIxICogbjQzIC0gbjExICogbjIyICogbjQzICkgKiBkZXRJbnY7XG5cblx0XHR0ZVsgMTIgXSA9IHQxNCAqIGRldEludjtcblx0XHR0ZVsgMTMgXSA9ICggbjEzICogbjI0ICogbjMxIC0gbjE0ICogbjIzICogbjMxICsgbjE0ICogbjIxICogbjMzIC0gbjExICogbjI0ICogbjMzIC0gbjEzICogbjIxICogbjM0ICsgbjExICogbjIzICogbjM0ICkgKiBkZXRJbnY7XG5cdFx0dGVbIDE0IF0gPSAoIG4xNCAqIG4yMiAqIG4zMSAtIG4xMiAqIG4yNCAqIG4zMSAtIG4xNCAqIG4yMSAqIG4zMiArIG4xMSAqIG4yNCAqIG4zMiArIG4xMiAqIG4yMSAqIG4zNCAtIG4xMSAqIG4yMiAqIG4zNCApICogZGV0SW52O1xuXHRcdHRlWyAxNSBdID0gKCBuMTIgKiBuMjMgKiBuMzEgLSBuMTMgKiBuMjIgKiBuMzEgKyBuMTMgKiBuMjEgKiBuMzIgLSBuMTEgKiBuMjMgKiBuMzIgLSBuMTIgKiBuMjEgKiBuMzMgKyBuMTEgKiBuMjIgKiBuMzMgKSAqIGRldEludjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2NhbGU6IGZ1bmN0aW9uICggdiApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cdFx0dmFyIHggPSB2LngsIHkgPSB2LnksIHogPSB2Lno7XG5cblx0XHR0ZVsgMCBdICo9IHg7IHRlWyA0IF0gKj0geTsgdGVbIDggXSAqPSB6O1xuXHRcdHRlWyAxIF0gKj0geDsgdGVbIDUgXSAqPSB5OyB0ZVsgOSBdICo9IHo7XG5cdFx0dGVbIDIgXSAqPSB4OyB0ZVsgNiBdICo9IHk7IHRlWyAxMCBdICo9IHo7XG5cdFx0dGVbIDMgXSAqPSB4OyB0ZVsgNyBdICo9IHk7IHRlWyAxMSBdICo9IHo7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldE1heFNjYWxlT25BeGlzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0dmFyIHNjYWxlWFNxID0gdGVbIDAgXSAqIHRlWyAwIF0gKyB0ZVsgMSBdICogdGVbIDEgXSArIHRlWyAyIF0gKiB0ZVsgMiBdO1xuXHRcdHZhciBzY2FsZVlTcSA9IHRlWyA0IF0gKiB0ZVsgNCBdICsgdGVbIDUgXSAqIHRlWyA1IF0gKyB0ZVsgNiBdICogdGVbIDYgXTtcblx0XHR2YXIgc2NhbGVaU3EgPSB0ZVsgOCBdICogdGVbIDggXSArIHRlWyA5IF0gKiB0ZVsgOSBdICsgdGVbIDEwIF0gKiB0ZVsgMTAgXTtcblxuXHRcdHJldHVybiBNYXRoLnNxcnQoIE1hdGgubWF4KCBzY2FsZVhTcSwgc2NhbGVZU3EsIHNjYWxlWlNxICkgKTtcblxuXHR9LFxuXG5cdG1ha2VUcmFuc2xhdGlvbjogZnVuY3Rpb24gKCB4LCB5LCB6ICkge1xuXG5cdFx0dGhpcy5zZXQoXG5cblx0XHRcdDEsIDAsIDAsIHgsXG5cdFx0XHQwLCAxLCAwLCB5LFxuXHRcdFx0MCwgMCwgMSwgeixcblx0XHRcdDAsIDAsIDAsIDFcblxuXHRcdCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG1ha2VSb3RhdGlvblg6IGZ1bmN0aW9uICggdGhldGEgKSB7XG5cblx0XHR2YXIgYyA9IE1hdGguY29zKCB0aGV0YSApLCBzID0gTWF0aC5zaW4oIHRoZXRhICk7XG5cblx0XHR0aGlzLnNldChcblxuXHRcdFx0MSwgMCwgIDAsIDAsXG5cdFx0XHQwLCBjLCAtIHMsIDAsXG5cdFx0XHQwLCBzLCAgYywgMCxcblx0XHRcdDAsIDAsICAwLCAxXG5cblx0XHQpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtYWtlUm90YXRpb25ZOiBmdW5jdGlvbiAoIHRoZXRhICkge1xuXG5cdFx0dmFyIGMgPSBNYXRoLmNvcyggdGhldGEgKSwgcyA9IE1hdGguc2luKCB0aGV0YSApO1xuXG5cdFx0dGhpcy5zZXQoXG5cblx0XHRcdCBjLCAwLCBzLCAwLFxuXHRcdFx0IDAsIDEsIDAsIDAsXG5cdFx0XHQtIHMsIDAsIGMsIDAsXG5cdFx0XHQgMCwgMCwgMCwgMVxuXG5cdFx0KTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWFrZVJvdGF0aW9uWjogZnVuY3Rpb24gKCB0aGV0YSApIHtcblxuXHRcdHZhciBjID0gTWF0aC5jb3MoIHRoZXRhICksIHMgPSBNYXRoLnNpbiggdGhldGEgKTtcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHRjLCAtIHMsIDAsIDAsXG5cdFx0XHRzLCAgYywgMCwgMCxcblx0XHRcdDAsICAwLCAxLCAwLFxuXHRcdFx0MCwgIDAsIDAsIDFcblxuXHRcdCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG1ha2VSb3RhdGlvbkF4aXM6IGZ1bmN0aW9uICggYXhpcywgYW5nbGUgKSB7XG5cblx0XHQvLyBCYXNlZCBvbiBodHRwOi8vd3d3LmdhbWVkZXYubmV0L3JlZmVyZW5jZS9hcnRpY2xlcy9hcnRpY2xlMTE5OS5hc3BcblxuXHRcdHZhciBjID0gTWF0aC5jb3MoIGFuZ2xlICk7XG5cdFx0dmFyIHMgPSBNYXRoLnNpbiggYW5nbGUgKTtcblx0XHR2YXIgdCA9IDEgLSBjO1xuXHRcdHZhciB4ID0gYXhpcy54LCB5ID0gYXhpcy55LCB6ID0gYXhpcy56O1xuXHRcdHZhciB0eCA9IHQgKiB4LCB0eSA9IHQgKiB5O1xuXG5cdFx0dGhpcy5zZXQoXG5cblx0XHRcdHR4ICogeCArIGMsIHR4ICogeSAtIHMgKiB6LCB0eCAqIHogKyBzICogeSwgMCxcblx0XHRcdHR4ICogeSArIHMgKiB6LCB0eSAqIHkgKyBjLCB0eSAqIHogLSBzICogeCwgMCxcblx0XHRcdHR4ICogeiAtIHMgKiB5LCB0eSAqIHogKyBzICogeCwgdCAqIHogKiB6ICsgYywgMCxcblx0XHRcdDAsIDAsIDAsIDFcblxuXHRcdCk7XG5cblx0XHQgcmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtYWtlU2NhbGU6IGZ1bmN0aW9uICggeCwgeSwgeiApIHtcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHR4LCAwLCAwLCAwLFxuXHRcdFx0MCwgeSwgMCwgMCxcblx0XHRcdDAsIDAsIHosIDAsXG5cdFx0XHQwLCAwLCAwLCAxXG5cblx0XHQpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtYWtlU2hlYXI6IGZ1bmN0aW9uICggeCwgeSwgeiApIHtcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHQxLCB5LCB6LCAwLFxuXHRcdFx0eCwgMSwgeiwgMCxcblx0XHRcdHgsIHksIDEsIDAsXG5cdFx0XHQwLCAwLCAwLCAxXG5cblx0XHQpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjb21wb3NlOiBmdW5jdGlvbiAoIHBvc2l0aW9uLCBxdWF0ZXJuaW9uLCBzY2FsZSApIHtcblxuXHRcdHRoaXMubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24oIHF1YXRlcm5pb24gKTtcblx0XHR0aGlzLnNjYWxlKCBzY2FsZSApO1xuXHRcdHRoaXMuc2V0UG9zaXRpb24oIHBvc2l0aW9uICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGRlY29tcG9zZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHZlY3RvciA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIG1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZGVjb21wb3NlKCBwb3NpdGlvbiwgcXVhdGVybmlvbiwgc2NhbGUgKSB7XG5cblx0XHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHRcdHZhciBzeCA9IHZlY3Rvci5zZXQoIHRlWyAwIF0sIHRlWyAxIF0sIHRlWyAyIF0gKS5sZW5ndGgoKTtcblx0XHRcdHZhciBzeSA9IHZlY3Rvci5zZXQoIHRlWyA0IF0sIHRlWyA1IF0sIHRlWyA2IF0gKS5sZW5ndGgoKTtcblx0XHRcdHZhciBzeiA9IHZlY3Rvci5zZXQoIHRlWyA4IF0sIHRlWyA5IF0sIHRlWyAxMCBdICkubGVuZ3RoKCk7XG5cblx0XHRcdC8vIGlmIGRldGVybWluZSBpcyBuZWdhdGl2ZSwgd2UgbmVlZCB0byBpbnZlcnQgb25lIHNjYWxlXG5cdFx0XHR2YXIgZGV0ID0gdGhpcy5kZXRlcm1pbmFudCgpO1xuXHRcdFx0aWYgKCBkZXQgPCAwICkgc3ggPSAtIHN4O1xuXG5cdFx0XHRwb3NpdGlvbi54ID0gdGVbIDEyIF07XG5cdFx0XHRwb3NpdGlvbi55ID0gdGVbIDEzIF07XG5cdFx0XHRwb3NpdGlvbi56ID0gdGVbIDE0IF07XG5cblx0XHRcdC8vIHNjYWxlIHRoZSByb3RhdGlvbiBwYXJ0XG5cdFx0XHRtYXRyaXguY29weSggdGhpcyApO1xuXG5cdFx0XHR2YXIgaW52U1ggPSAxIC8gc3g7XG5cdFx0XHR2YXIgaW52U1kgPSAxIC8gc3k7XG5cdFx0XHR2YXIgaW52U1ogPSAxIC8gc3o7XG5cblx0XHRcdG1hdHJpeC5lbGVtZW50c1sgMCBdICo9IGludlNYO1xuXHRcdFx0bWF0cml4LmVsZW1lbnRzWyAxIF0gKj0gaW52U1g7XG5cdFx0XHRtYXRyaXguZWxlbWVudHNbIDIgXSAqPSBpbnZTWDtcblxuXHRcdFx0bWF0cml4LmVsZW1lbnRzWyA0IF0gKj0gaW52U1k7XG5cdFx0XHRtYXRyaXguZWxlbWVudHNbIDUgXSAqPSBpbnZTWTtcblx0XHRcdG1hdHJpeC5lbGVtZW50c1sgNiBdICo9IGludlNZO1xuXG5cdFx0XHRtYXRyaXguZWxlbWVudHNbIDggXSAqPSBpbnZTWjtcblx0XHRcdG1hdHJpeC5lbGVtZW50c1sgOSBdICo9IGludlNaO1xuXHRcdFx0bWF0cml4LmVsZW1lbnRzWyAxMCBdICo9IGludlNaO1xuXG5cdFx0XHRxdWF0ZXJuaW9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCggbWF0cml4ICk7XG5cblx0XHRcdHNjYWxlLnggPSBzeDtcblx0XHRcdHNjYWxlLnkgPSBzeTtcblx0XHRcdHNjYWxlLnogPSBzejtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRtYWtlUGVyc3BlY3RpdmU6IGZ1bmN0aW9uICggbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tLCBuZWFyLCBmYXIgKSB7XG5cblx0XHRpZiAoIGZhciA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRyaXg0OiAubWFrZVBlcnNwZWN0aXZlKCkgaGFzIGJlZW4gcmVkZWZpbmVkIGFuZCBoYXMgYSBuZXcgc2lnbmF0dXJlLiBQbGVhc2UgY2hlY2sgdGhlIGRvY3MuJyApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHRlID0gdGhpcy5lbGVtZW50cztcblx0XHR2YXIgeCA9IDIgKiBuZWFyIC8gKCByaWdodCAtIGxlZnQgKTtcblx0XHR2YXIgeSA9IDIgKiBuZWFyIC8gKCB0b3AgLSBib3R0b20gKTtcblxuXHRcdHZhciBhID0gKCByaWdodCArIGxlZnQgKSAvICggcmlnaHQgLSBsZWZ0ICk7XG5cdFx0dmFyIGIgPSAoIHRvcCArIGJvdHRvbSApIC8gKCB0b3AgLSBib3R0b20gKTtcblx0XHR2YXIgYyA9IC0gKCBmYXIgKyBuZWFyICkgLyAoIGZhciAtIG5lYXIgKTtcblx0XHR2YXIgZCA9IC0gMiAqIGZhciAqIG5lYXIgLyAoIGZhciAtIG5lYXIgKTtcblxuXHRcdHRlWyAwIF0gPSB4O1x0dGVbIDQgXSA9IDA7XHR0ZVsgOCBdID0gYTtcdHRlWyAxMiBdID0gMDtcblx0XHR0ZVsgMSBdID0gMDtcdHRlWyA1IF0gPSB5O1x0dGVbIDkgXSA9IGI7XHR0ZVsgMTMgXSA9IDA7XG5cdFx0dGVbIDIgXSA9IDA7XHR0ZVsgNiBdID0gMDtcdHRlWyAxMCBdID0gYztcdHRlWyAxNCBdID0gZDtcblx0XHR0ZVsgMyBdID0gMDtcdHRlWyA3IF0gPSAwO1x0dGVbIDExIF0gPSAtIDE7XHR0ZVsgMTUgXSA9IDA7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG1ha2VPcnRob2dyYXBoaWM6IGZ1bmN0aW9uICggbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tLCBuZWFyLCBmYXIgKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdHZhciB3ID0gMS4wIC8gKCByaWdodCAtIGxlZnQgKTtcblx0XHR2YXIgaCA9IDEuMCAvICggdG9wIC0gYm90dG9tICk7XG5cdFx0dmFyIHAgPSAxLjAgLyAoIGZhciAtIG5lYXIgKTtcblxuXHRcdHZhciB4ID0gKCByaWdodCArIGxlZnQgKSAqIHc7XG5cdFx0dmFyIHkgPSAoIHRvcCArIGJvdHRvbSApICogaDtcblx0XHR2YXIgeiA9ICggZmFyICsgbmVhciApICogcDtcblxuXHRcdHRlWyAwIF0gPSAyICogdztcdHRlWyA0IF0gPSAwO1x0dGVbIDggXSA9IDA7XHR0ZVsgMTIgXSA9IC0geDtcblx0XHR0ZVsgMSBdID0gMDtcdHRlWyA1IF0gPSAyICogaDtcdHRlWyA5IF0gPSAwO1x0dGVbIDEzIF0gPSAtIHk7XG5cdFx0dGVbIDIgXSA9IDA7XHR0ZVsgNiBdID0gMDtcdHRlWyAxMCBdID0gLSAyICogcDtcdHRlWyAxNCBdID0gLSB6O1xuXHRcdHRlWyAzIF0gPSAwO1x0dGVbIDcgXSA9IDA7XHR0ZVsgMTEgXSA9IDA7XHR0ZVsgMTUgXSA9IDE7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGVxdWFsczogZnVuY3Rpb24gKCBtYXRyaXggKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdHZhciBtZSA9IG1hdHJpeC5lbGVtZW50cztcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IDE2OyBpICsrICkge1xuXG5cdFx0XHRpZiAoIHRlWyBpIF0gIT09IG1lWyBpIF0gKSByZXR1cm4gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblxuXHR9LFxuXG5cdGZyb21BcnJheTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIG9mZnNldCA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCAxNjsgaSArKyApIHtcblxuXHRcdFx0dGhpcy5lbGVtZW50c1sgaSBdID0gYXJyYXlbIGkgKyBvZmZzZXQgXTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0dG9BcnJheTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBhcnJheSA9PT0gdW5kZWZpbmVkICkgYXJyYXkgPSBbXTtcblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHRhcnJheVsgb2Zmc2V0IF0gPSB0ZVsgMCBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAxIF0gPSB0ZVsgMSBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAyIF0gPSB0ZVsgMiBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAzIF0gPSB0ZVsgMyBdO1xuXG5cdFx0YXJyYXlbIG9mZnNldCArIDQgXSA9IHRlWyA0IF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDUgXSA9IHRlWyA1IF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDYgXSA9IHRlWyA2IF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDcgXSA9IHRlWyA3IF07XG5cblx0XHRhcnJheVsgb2Zmc2V0ICsgOCBdID0gdGVbIDggXTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgOSBdID0gdGVbIDkgXTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMTAgXSA9IHRlWyAxMCBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAxMSBdID0gdGVbIDExIF07XG5cblx0XHRhcnJheVsgb2Zmc2V0ICsgMTIgXSA9IHRlWyAxMiBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAxMyBdID0gdGVbIDEzIF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDE0IF0gPSB0ZVsgMTQgXTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMTUgXSA9IHRlWyAxNSBdO1xuXG5cdFx0cmV0dXJuIGFycmF5O1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gRGF0YVRleHR1cmUoIGRhdGEsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgbWFwcGluZywgd3JhcFMsIHdyYXBULCBtYWdGaWx0ZXIsIG1pbkZpbHRlciwgYW5pc290cm9weSwgZW5jb2RpbmcgKSB7XG5cblx0VGV4dHVyZS5jYWxsKCB0aGlzLCBudWxsLCBtYXBwaW5nLCB3cmFwUywgd3JhcFQsIG1hZ0ZpbHRlciwgbWluRmlsdGVyLCBmb3JtYXQsIHR5cGUsIGFuaXNvdHJvcHksIGVuY29kaW5nICk7XG5cblx0dGhpcy5pbWFnZSA9IHsgZGF0YTogZGF0YSwgd2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCB9O1xuXG5cdHRoaXMubWFnRmlsdGVyID0gbWFnRmlsdGVyICE9PSB1bmRlZmluZWQgPyBtYWdGaWx0ZXIgOiBOZWFyZXN0RmlsdGVyO1xuXHR0aGlzLm1pbkZpbHRlciA9IG1pbkZpbHRlciAhPT0gdW5kZWZpbmVkID8gbWluRmlsdGVyIDogTmVhcmVzdEZpbHRlcjtcblxuXHR0aGlzLmdlbmVyYXRlTWlwbWFwcyA9IGZhbHNlO1xuXHR0aGlzLmZsaXBZID0gZmFsc2U7XG5cdHRoaXMudW5wYWNrQWxpZ25tZW50ID0gMTtcblxufVxuXG5EYXRhVGV4dHVyZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBUZXh0dXJlLnByb3RvdHlwZSApO1xuRGF0YVRleHR1cmUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRGF0YVRleHR1cmU7XG5cbkRhdGFUZXh0dXJlLnByb3RvdHlwZS5pc0RhdGFUZXh0dXJlID0gdHJ1ZTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEN1YmVUZXh0dXJlKCBpbWFnZXMsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSwgZW5jb2RpbmcgKSB7XG5cblx0aW1hZ2VzID0gaW1hZ2VzICE9PSB1bmRlZmluZWQgPyBpbWFnZXMgOiBbXTtcblx0bWFwcGluZyA9IG1hcHBpbmcgIT09IHVuZGVmaW5lZCA/IG1hcHBpbmcgOiBDdWJlUmVmbGVjdGlvbk1hcHBpbmc7XG5cblx0VGV4dHVyZS5jYWxsKCB0aGlzLCBpbWFnZXMsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSwgZW5jb2RpbmcgKTtcblxuXHR0aGlzLmZsaXBZID0gZmFsc2U7XG5cbn1cblxuQ3ViZVRleHR1cmUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggVGV4dHVyZS5wcm90b3R5cGUgKTtcbkN1YmVUZXh0dXJlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEN1YmVUZXh0dXJlO1xuXG5DdWJlVGV4dHVyZS5wcm90b3R5cGUuaXNDdWJlVGV4dHVyZSA9IHRydWU7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eSggQ3ViZVRleHR1cmUucHJvdG90eXBlLCAnaW1hZ2VzJywge1xuXG5cdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuaW1hZ2U7XG5cblx0fSxcblxuXHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLmltYWdlID0gdmFsdWU7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciB0c2Nod1xuICpcbiAqIFVuaWZvcm1zIG9mIGEgcHJvZ3JhbS5cbiAqIFRob3NlIGZvcm0gYSB0cmVlIHN0cnVjdHVyZSB3aXRoIGEgc3BlY2lhbCB0b3AtbGV2ZWwgY29udGFpbmVyIGZvciB0aGUgcm9vdCxcbiAqIHdoaWNoIHlvdSBnZXQgYnkgY2FsbGluZyAnbmV3IFdlYkdMVW5pZm9ybXMoIGdsLCBwcm9ncmFtLCByZW5kZXJlciApJy5cbiAqXG4gKlxuICogUHJvcGVydGllcyBvZiBpbm5lciBub2RlcyBpbmNsdWRpbmcgdGhlIHRvcC1sZXZlbCBjb250YWluZXI6XG4gKlxuICogLnNlcSAtIGFycmF5IG9mIG5lc3RlZCB1bmlmb3Jtc1xuICogLm1hcCAtIG5lc3RlZCB1bmlmb3JtcyBieSBuYW1lXG4gKlxuICpcbiAqIE1ldGhvZHMgb2YgYWxsIG5vZGVzIGV4Y2VwdCB0aGUgdG9wLWxldmVsIGNvbnRhaW5lcjpcbiAqXG4gKiAuc2V0VmFsdWUoIGdsLCB2YWx1ZSwgW3JlbmRlcmVyXSApXG4gKlxuICogXHRcdHVwbG9hZHMgYSB1bmlmb3JtIHZhbHVlKHMpXG4gKiAgXHR0aGUgJ3JlbmRlcmVyJyBwYXJhbWV0ZXIgaXMgbmVlZGVkIGZvciBzYW1wbGVyIHVuaWZvcm1zXG4gKlxuICpcbiAqIFN0YXRpYyBtZXRob2RzIG9mIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyIChyZW5kZXJlciBmYWN0b3JpemF0aW9ucyk6XG4gKlxuICogLnVwbG9hZCggZ2wsIHNlcSwgdmFsdWVzLCByZW5kZXJlciApXG4gKlxuICogXHRcdHNldHMgdW5pZm9ybXMgaW4gJ3NlcScgdG8gJ3ZhbHVlc1tpZF0udmFsdWUnXG4gKlxuICogLnNlcVdpdGhWYWx1ZSggc2VxLCB2YWx1ZXMgKSA6IGZpbHRlcmVkU2VxXG4gKlxuICogXHRcdGZpbHRlcnMgJ3NlcScgZW50cmllcyB3aXRoIGNvcnJlc3BvbmRpbmcgZW50cnkgaW4gdmFsdWVzXG4gKlxuICpcbiAqIE1ldGhvZHMgb2YgdGhlIHRvcC1sZXZlbCBjb250YWluZXIgKHJlbmRlcmVyIGZhY3Rvcml6YXRpb25zKTpcbiAqXG4gKiAuc2V0VmFsdWUoIGdsLCBuYW1lLCB2YWx1ZSApXG4gKlxuICogXHRcdHNldHMgdW5pZm9ybSB3aXRoICBuYW1lICduYW1lJyB0byAndmFsdWUnXG4gKlxuICogLnNldCggZ2wsIG9iaiwgcHJvcCApXG4gKlxuICogXHRcdHNldHMgdW5pZm9ybSBmcm9tIG9iamVjdCBhbmQgcHJvcGVydHkgd2l0aCBzYW1lIG5hbWUgdGhhbiB1bmlmb3JtXG4gKlxuICogLnNldE9wdGlvbmFsKCBnbCwgb2JqLCBwcm9wIClcbiAqXG4gKiBcdFx0bGlrZSAuc2V0IGZvciBhbiBvcHRpb25hbCBwcm9wZXJ0eSBvZiB0aGUgb2JqZWN0XG4gKlxuICovXG5cbnZhciBlbXB0eVRleHR1cmUgPSBuZXcgVGV4dHVyZSgpO1xudmFyIGVtcHR5Q3ViZVRleHR1cmUgPSBuZXcgQ3ViZVRleHR1cmUoKTtcblxuLy8gLS0tIEJhc2UgZm9yIGlubmVyIG5vZGVzIChpbmNsdWRpbmcgdGhlIHJvb3QpIC0tLVxuXG5mdW5jdGlvbiBVbmlmb3JtQ29udGFpbmVyKCkge1xuXG5cdHRoaXMuc2VxID0gW107XG5cdHRoaXMubWFwID0ge307XG5cbn1cblxuLy8gLS0tIFV0aWxpdGllcyAtLS1cblxuLy8gQXJyYXkgQ2FjaGVzIChwcm92aWRlIHR5cGVkIGFycmF5cyBmb3IgdGVtcG9yYXJ5IGJ5IHNpemUpXG5cbnZhciBhcnJheUNhY2hlRjMyID0gW107XG52YXIgYXJyYXlDYWNoZUkzMiA9IFtdO1xuXG4vLyBGbG9hdDMyQXJyYXkgY2FjaGVzIHVzZWQgZm9yIHVwbG9hZGluZyBNYXRyaXggdW5pZm9ybXNcblxudmFyIG1hdDRhcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkoIDE2ICk7XG52YXIgbWF0M2FycmF5ID0gbmV3IEZsb2F0MzJBcnJheSggOSApO1xuXG4vLyBGbGF0dGVuaW5nIGZvciBhcnJheXMgb2YgdmVjdG9ycyBhbmQgbWF0cmljZXNcblxuZnVuY3Rpb24gZmxhdHRlbiggYXJyYXksIG5CbG9ja3MsIGJsb2NrU2l6ZSApIHtcblxuXHR2YXIgZmlyc3RFbGVtID0gYXJyYXlbIDAgXTtcblxuXHRpZiAoIGZpcnN0RWxlbSA8PSAwIHx8IGZpcnN0RWxlbSA+IDAgKSByZXR1cm4gYXJyYXk7XG5cdC8vIHVub3B0aW1pemVkOiAhIGlzTmFOKCBmaXJzdEVsZW0gKVxuXHQvLyBzZWUgaHR0cDovL2phY2tzb25kdW5zdGFuLmNvbS9hcnRpY2xlcy85ODNcblxuXHR2YXIgbiA9IG5CbG9ja3MgKiBibG9ja1NpemUsXG5cdFx0ciA9IGFycmF5Q2FjaGVGMzJbIG4gXTtcblxuXHRpZiAoIHIgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdHIgPSBuZXcgRmxvYXQzMkFycmF5KCBuICk7XG5cdFx0YXJyYXlDYWNoZUYzMlsgbiBdID0gcjtcblxuXHR9XG5cblx0aWYgKCBuQmxvY2tzICE9PSAwICkge1xuXG5cdFx0Zmlyc3RFbGVtLnRvQXJyYXkoIHIsIDAgKTtcblxuXHRcdGZvciAoIHZhciBpID0gMSwgb2Zmc2V0ID0gMDsgaSAhPT0gbkJsb2NrczsgKysgaSApIHtcblxuXHRcdFx0b2Zmc2V0ICs9IGJsb2NrU2l6ZTtcblx0XHRcdGFycmF5WyBpIF0udG9BcnJheSggciwgb2Zmc2V0ICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdHJldHVybiByO1xuXG59XG5cbi8vIFRleHR1cmUgdW5pdCBhbGxvY2F0aW9uXG5cbmZ1bmN0aW9uIGFsbG9jVGV4VW5pdHMoIHJlbmRlcmVyLCBuICkge1xuXG5cdHZhciByID0gYXJyYXlDYWNoZUkzMlsgbiBdO1xuXG5cdGlmICggciA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0ciA9IG5ldyBJbnQzMkFycmF5KCBuICk7XG5cdFx0YXJyYXlDYWNoZUkzMlsgbiBdID0gcjtcblxuXHR9XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuOyArKyBpIClcblx0XHRyWyBpIF0gPSByZW5kZXJlci5hbGxvY1RleHR1cmVVbml0KCk7XG5cblx0cmV0dXJuIHI7XG5cbn1cblxuLy8gLS0tIFNldHRlcnMgLS0tXG5cbi8vIE5vdGU6IERlZmluaW5nIHRoZXNlIG1ldGhvZHMgZXh0ZXJuYWxseSwgYmVjYXVzZSB0aGV5IGNvbWUgaW4gYSBidW5jaFxuLy8gYW5kIHRoaXMgd2F5IHRoZWlyIG5hbWVzIG1pbmlmeS5cblxuLy8gU2luZ2xlIHNjYWxhclxuXG5mdW5jdGlvbiBzZXRWYWx1ZTFmKCBnbCwgdiApIHsgZ2wudW5pZm9ybTFmKCB0aGlzLmFkZHIsIHYgKTsgfVxuZnVuY3Rpb24gc2V0VmFsdWUxaSggZ2wsIHYgKSB7IGdsLnVuaWZvcm0xaSggdGhpcy5hZGRyLCB2ICk7IH1cblxuLy8gU2luZ2xlIGZsb2F0IHZlY3RvciAoZnJvbSBmbGF0IGFycmF5IG9yIFRIUkVFLlZlY3Rvck4pXG5cbmZ1bmN0aW9uIHNldFZhbHVlMmZ2KCBnbCwgdiApIHtcblxuXHRpZiAoIHYueCA9PT0gdW5kZWZpbmVkICkgZ2wudW5pZm9ybTJmdiggdGhpcy5hZGRyLCB2ICk7XG5cdGVsc2UgZ2wudW5pZm9ybTJmKCB0aGlzLmFkZHIsIHYueCwgdi55ICk7XG5cbn1cblxuZnVuY3Rpb24gc2V0VmFsdWUzZnYoIGdsLCB2ICkge1xuXG5cdGlmICggdi54ICE9PSB1bmRlZmluZWQgKVxuXHRcdGdsLnVuaWZvcm0zZiggdGhpcy5hZGRyLCB2LngsIHYueSwgdi56ICk7XG5cdGVsc2UgaWYgKCB2LnIgIT09IHVuZGVmaW5lZCApXG5cdFx0Z2wudW5pZm9ybTNmKCB0aGlzLmFkZHIsIHYuciwgdi5nLCB2LmIgKTtcblx0ZWxzZVxuXHRcdGdsLnVuaWZvcm0zZnYoIHRoaXMuYWRkciwgdiApO1xuXG59XG5cbmZ1bmN0aW9uIHNldFZhbHVlNGZ2KCBnbCwgdiApIHtcblxuXHRpZiAoIHYueCA9PT0gdW5kZWZpbmVkICkgZ2wudW5pZm9ybTRmdiggdGhpcy5hZGRyLCB2ICk7XG5cdGVsc2UgZ2wudW5pZm9ybTRmKCB0aGlzLmFkZHIsIHYueCwgdi55LCB2LnosIHYudyApO1xuXG59XG5cbi8vIFNpbmdsZSBtYXRyaXggKGZyb20gZmxhdCBhcnJheSBvciBNYXRyaXhOKVxuXG5mdW5jdGlvbiBzZXRWYWx1ZTJmbSggZ2wsIHYgKSB7XG5cblx0Z2wudW5pZm9ybU1hdHJpeDJmdiggdGhpcy5hZGRyLCBmYWxzZSwgdi5lbGVtZW50cyB8fCB2ICk7XG5cbn1cblxuZnVuY3Rpb24gc2V0VmFsdWUzZm0oIGdsLCB2ICkge1xuXG5cdGlmICggdi5lbGVtZW50cyA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0Z2wudW5pZm9ybU1hdHJpeDNmdiggdGhpcy5hZGRyLCBmYWxzZSwgdiApO1xuXG5cdH0gZWxzZSB7XG5cblx0XHRtYXQzYXJyYXkuc2V0KCB2LmVsZW1lbnRzICk7XG5cdFx0Z2wudW5pZm9ybU1hdHJpeDNmdiggdGhpcy5hZGRyLCBmYWxzZSwgbWF0M2FycmF5ICk7XG5cblx0fVxuXG59XG5cbmZ1bmN0aW9uIHNldFZhbHVlNGZtKCBnbCwgdiApIHtcblxuXHRpZiAoIHYuZWxlbWVudHMgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdGdsLnVuaWZvcm1NYXRyaXg0ZnYoIHRoaXMuYWRkciwgZmFsc2UsIHYgKTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0bWF0NGFycmF5LnNldCggdi5lbGVtZW50cyApO1xuXHRcdGdsLnVuaWZvcm1NYXRyaXg0ZnYoIHRoaXMuYWRkciwgZmFsc2UsIG1hdDRhcnJheSApO1xuXG5cdH1cblxufVxuXG4vLyBTaW5nbGUgdGV4dHVyZSAoMkQgLyBDdWJlKVxuXG5mdW5jdGlvbiBzZXRWYWx1ZVQxKCBnbCwgdiwgcmVuZGVyZXIgKSB7XG5cblx0dmFyIHVuaXQgPSByZW5kZXJlci5hbGxvY1RleHR1cmVVbml0KCk7XG5cdGdsLnVuaWZvcm0xaSggdGhpcy5hZGRyLCB1bml0ICk7XG5cdHJlbmRlcmVyLnNldFRleHR1cmUyRCggdiB8fCBlbXB0eVRleHR1cmUsIHVuaXQgKTtcblxufVxuXG5mdW5jdGlvbiBzZXRWYWx1ZVQ2KCBnbCwgdiwgcmVuZGVyZXIgKSB7XG5cblx0dmFyIHVuaXQgPSByZW5kZXJlci5hbGxvY1RleHR1cmVVbml0KCk7XG5cdGdsLnVuaWZvcm0xaSggdGhpcy5hZGRyLCB1bml0ICk7XG5cdHJlbmRlcmVyLnNldFRleHR1cmVDdWJlKCB2IHx8IGVtcHR5Q3ViZVRleHR1cmUsIHVuaXQgKTtcblxufVxuXG4vLyBJbnRlZ2VyIC8gQm9vbGVhbiB2ZWN0b3JzIG9yIGFycmF5cyB0aGVyZW9mIChhbHdheXMgZmxhdCBhcnJheXMpXG5cbmZ1bmN0aW9uIHNldFZhbHVlMml2KCBnbCwgdiApIHsgZ2wudW5pZm9ybTJpdiggdGhpcy5hZGRyLCB2ICk7IH1cbmZ1bmN0aW9uIHNldFZhbHVlM2l2KCBnbCwgdiApIHsgZ2wudW5pZm9ybTNpdiggdGhpcy5hZGRyLCB2ICk7IH1cbmZ1bmN0aW9uIHNldFZhbHVlNGl2KCBnbCwgdiApIHsgZ2wudW5pZm9ybTRpdiggdGhpcy5hZGRyLCB2ICk7IH1cblxuLy8gSGVscGVyIHRvIHBpY2sgdGhlIHJpZ2h0IHNldHRlciBmb3IgdGhlIHNpbmd1bGFyIGNhc2VcblxuZnVuY3Rpb24gZ2V0U2luZ3VsYXJTZXR0ZXIoIHR5cGUgKSB7XG5cblx0c3dpdGNoICggdHlwZSApIHtcblxuXHRcdGNhc2UgMHgxNDA2OiByZXR1cm4gc2V0VmFsdWUxZjsgLy8gRkxPQVRcblx0XHRjYXNlIDB4OGI1MDogcmV0dXJuIHNldFZhbHVlMmZ2OyAvLyBfVkVDMlxuXHRcdGNhc2UgMHg4YjUxOiByZXR1cm4gc2V0VmFsdWUzZnY7IC8vIF9WRUMzXG5cdFx0Y2FzZSAweDhiNTI6IHJldHVybiBzZXRWYWx1ZTRmdjsgLy8gX1ZFQzRcblxuXHRcdGNhc2UgMHg4YjVhOiByZXR1cm4gc2V0VmFsdWUyZm07IC8vIF9NQVQyXG5cdFx0Y2FzZSAweDhiNWI6IHJldHVybiBzZXRWYWx1ZTNmbTsgLy8gX01BVDNcblx0XHRjYXNlIDB4OGI1YzogcmV0dXJuIHNldFZhbHVlNGZtOyAvLyBfTUFUNFxuXG5cdFx0Y2FzZSAweDhiNWU6IHJldHVybiBzZXRWYWx1ZVQxOyAvLyBTQU1QTEVSXzJEXG5cdFx0Y2FzZSAweDhiNjA6IHJldHVybiBzZXRWYWx1ZVQ2OyAvLyBTQU1QTEVSX0NVQkVcblxuXHRcdGNhc2UgMHgxNDA0OiBjYXNlIDB4OGI1NjogcmV0dXJuIHNldFZhbHVlMWk7IC8vIElOVCwgQk9PTFxuXHRcdGNhc2UgMHg4YjUzOiBjYXNlIDB4OGI1NzogcmV0dXJuIHNldFZhbHVlMml2OyAvLyBfVkVDMlxuXHRcdGNhc2UgMHg4YjU0OiBjYXNlIDB4OGI1ODogcmV0dXJuIHNldFZhbHVlM2l2OyAvLyBfVkVDM1xuXHRcdGNhc2UgMHg4YjU1OiBjYXNlIDB4OGI1OTogcmV0dXJuIHNldFZhbHVlNGl2OyAvLyBfVkVDNFxuXG5cdH1cblxufVxuXG4vLyBBcnJheSBvZiBzY2FsYXJzXG5cbmZ1bmN0aW9uIHNldFZhbHVlMWZ2KCBnbCwgdiApIHsgZ2wudW5pZm9ybTFmdiggdGhpcy5hZGRyLCB2ICk7IH1cbmZ1bmN0aW9uIHNldFZhbHVlMWl2KCBnbCwgdiApIHsgZ2wudW5pZm9ybTFpdiggdGhpcy5hZGRyLCB2ICk7IH1cblxuLy8gQXJyYXkgb2YgdmVjdG9ycyAoZmxhdCBvciBmcm9tIFRIUkVFIGNsYXNzZXMpXG5cbmZ1bmN0aW9uIHNldFZhbHVlVjJhKCBnbCwgdiApIHtcblxuXHRnbC51bmlmb3JtMmZ2KCB0aGlzLmFkZHIsIGZsYXR0ZW4oIHYsIHRoaXMuc2l6ZSwgMiApICk7XG5cbn1cblxuZnVuY3Rpb24gc2V0VmFsdWVWM2EoIGdsLCB2ICkge1xuXG5cdGdsLnVuaWZvcm0zZnYoIHRoaXMuYWRkciwgZmxhdHRlbiggdiwgdGhpcy5zaXplLCAzICkgKTtcblxufVxuXG5mdW5jdGlvbiBzZXRWYWx1ZVY0YSggZ2wsIHYgKSB7XG5cblx0Z2wudW5pZm9ybTRmdiggdGhpcy5hZGRyLCBmbGF0dGVuKCB2LCB0aGlzLnNpemUsIDQgKSApO1xuXG59XG5cbi8vIEFycmF5IG9mIG1hdHJpY2VzIChmbGF0IG9yIGZyb20gVEhSRUUgY2xhc2VzKVxuXG5mdW5jdGlvbiBzZXRWYWx1ZU0yYSggZ2wsIHYgKSB7XG5cblx0Z2wudW5pZm9ybU1hdHJpeDJmdiggdGhpcy5hZGRyLCBmYWxzZSwgZmxhdHRlbiggdiwgdGhpcy5zaXplLCA0ICkgKTtcblxufVxuXG5mdW5jdGlvbiBzZXRWYWx1ZU0zYSggZ2wsIHYgKSB7XG5cblx0Z2wudW5pZm9ybU1hdHJpeDNmdiggdGhpcy5hZGRyLCBmYWxzZSwgZmxhdHRlbiggdiwgdGhpcy5zaXplLCA5ICkgKTtcblxufVxuXG5mdW5jdGlvbiBzZXRWYWx1ZU00YSggZ2wsIHYgKSB7XG5cblx0Z2wudW5pZm9ybU1hdHJpeDRmdiggdGhpcy5hZGRyLCBmYWxzZSwgZmxhdHRlbiggdiwgdGhpcy5zaXplLCAxNiApICk7XG5cbn1cblxuLy8gQXJyYXkgb2YgdGV4dHVyZXMgKDJEIC8gQ3ViZSlcblxuZnVuY3Rpb24gc2V0VmFsdWVUMWEoIGdsLCB2LCByZW5kZXJlciApIHtcblxuXHR2YXIgbiA9IHYubGVuZ3RoLFxuXHRcdHVuaXRzID0gYWxsb2NUZXhVbml0cyggcmVuZGVyZXIsIG4gKTtcblxuXHRnbC51bmlmb3JtMWl2KCB0aGlzLmFkZHIsIHVuaXRzICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0cmVuZGVyZXIuc2V0VGV4dHVyZTJEKCB2WyBpIF0gfHwgZW1wdHlUZXh0dXJlLCB1bml0c1sgaSBdICk7XG5cblx0fVxuXG59XG5cbmZ1bmN0aW9uIHNldFZhbHVlVDZhKCBnbCwgdiwgcmVuZGVyZXIgKSB7XG5cblx0dmFyIG4gPSB2Lmxlbmd0aCxcblx0XHR1bml0cyA9IGFsbG9jVGV4VW5pdHMoIHJlbmRlcmVyLCBuICk7XG5cblx0Z2wudW5pZm9ybTFpdiggdGhpcy5hZGRyLCB1bml0cyApO1xuXG5cdGZvciAoIHZhciBpID0gMDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdHJlbmRlcmVyLnNldFRleHR1cmVDdWJlKCB2WyBpIF0gfHwgZW1wdHlDdWJlVGV4dHVyZSwgdW5pdHNbIGkgXSApO1xuXG5cdH1cblxufVxuXG4vLyBIZWxwZXIgdG8gcGljayB0aGUgcmlnaHQgc2V0dGVyIGZvciBhIHB1cmUgKGJvdHRvbS1sZXZlbCkgYXJyYXlcblxuZnVuY3Rpb24gZ2V0UHVyZUFycmF5U2V0dGVyKCB0eXBlICkge1xuXG5cdHN3aXRjaCAoIHR5cGUgKSB7XG5cblx0XHRjYXNlIDB4MTQwNjogcmV0dXJuIHNldFZhbHVlMWZ2OyAvLyBGTE9BVFxuXHRcdGNhc2UgMHg4YjUwOiByZXR1cm4gc2V0VmFsdWVWMmE7IC8vIF9WRUMyXG5cdFx0Y2FzZSAweDhiNTE6IHJldHVybiBzZXRWYWx1ZVYzYTsgLy8gX1ZFQzNcblx0XHRjYXNlIDB4OGI1MjogcmV0dXJuIHNldFZhbHVlVjRhOyAvLyBfVkVDNFxuXG5cdFx0Y2FzZSAweDhiNWE6IHJldHVybiBzZXRWYWx1ZU0yYTsgLy8gX01BVDJcblx0XHRjYXNlIDB4OGI1YjogcmV0dXJuIHNldFZhbHVlTTNhOyAvLyBfTUFUM1xuXHRcdGNhc2UgMHg4YjVjOiByZXR1cm4gc2V0VmFsdWVNNGE7IC8vIF9NQVQ0XG5cblx0XHRjYXNlIDB4OGI1ZTogcmV0dXJuIHNldFZhbHVlVDFhOyAvLyBTQU1QTEVSXzJEXG5cdFx0Y2FzZSAweDhiNjA6IHJldHVybiBzZXRWYWx1ZVQ2YTsgLy8gU0FNUExFUl9DVUJFXG5cblx0XHRjYXNlIDB4MTQwNDogY2FzZSAweDhiNTY6IHJldHVybiBzZXRWYWx1ZTFpdjsgLy8gSU5ULCBCT09MXG5cdFx0Y2FzZSAweDhiNTM6IGNhc2UgMHg4YjU3OiByZXR1cm4gc2V0VmFsdWUyaXY7IC8vIF9WRUMyXG5cdFx0Y2FzZSAweDhiNTQ6IGNhc2UgMHg4YjU4OiByZXR1cm4gc2V0VmFsdWUzaXY7IC8vIF9WRUMzXG5cdFx0Y2FzZSAweDhiNTU6IGNhc2UgMHg4YjU5OiByZXR1cm4gc2V0VmFsdWU0aXY7IC8vIF9WRUM0XG5cblx0fVxuXG59XG5cbi8vIC0tLSBVbmlmb3JtIENsYXNzZXMgLS0tXG5cbmZ1bmN0aW9uIFNpbmdsZVVuaWZvcm0oIGlkLCBhY3RpdmVJbmZvLCBhZGRyICkge1xuXG5cdHRoaXMuaWQgPSBpZDtcblx0dGhpcy5hZGRyID0gYWRkcjtcblx0dGhpcy5zZXRWYWx1ZSA9IGdldFNpbmd1bGFyU2V0dGVyKCBhY3RpdmVJbmZvLnR5cGUgKTtcblxuXHQvLyB0aGlzLnBhdGggPSBhY3RpdmVJbmZvLm5hbWU7IC8vIERFQlVHXG5cbn1cblxuZnVuY3Rpb24gUHVyZUFycmF5VW5pZm9ybSggaWQsIGFjdGl2ZUluZm8sIGFkZHIgKSB7XG5cblx0dGhpcy5pZCA9IGlkO1xuXHR0aGlzLmFkZHIgPSBhZGRyO1xuXHR0aGlzLnNpemUgPSBhY3RpdmVJbmZvLnNpemU7XG5cdHRoaXMuc2V0VmFsdWUgPSBnZXRQdXJlQXJyYXlTZXR0ZXIoIGFjdGl2ZUluZm8udHlwZSApO1xuXG5cdC8vIHRoaXMucGF0aCA9IGFjdGl2ZUluZm8ubmFtZTsgLy8gREVCVUdcblxufVxuXG5mdW5jdGlvbiBTdHJ1Y3R1cmVkVW5pZm9ybSggaWQgKSB7XG5cblx0dGhpcy5pZCA9IGlkO1xuXG5cdFVuaWZvcm1Db250YWluZXIuY2FsbCggdGhpcyApOyAvLyBtaXgtaW5cblxufVxuXG5TdHJ1Y3R1cmVkVW5pZm9ybS5wcm90b3R5cGUuc2V0VmFsdWUgPSBmdW5jdGlvbiAoIGdsLCB2YWx1ZSApIHtcblxuXHQvLyBOb3RlOiBEb24ndCBuZWVkIGFuIGV4dHJhICdyZW5kZXJlcicgcGFyYW1ldGVyLCBzaW5jZSBzYW1wbGVyc1xuXHQvLyBhcmUgbm90IGFsbG93ZWQgaW4gc3RydWN0dXJlZCB1bmlmb3Jtcy5cblxuXHR2YXIgc2VxID0gdGhpcy5zZXE7XG5cblx0Zm9yICggdmFyIGkgPSAwLCBuID0gc2VxLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdHZhciB1ID0gc2VxWyBpIF07XG5cdFx0dS5zZXRWYWx1ZSggZ2wsIHZhbHVlWyB1LmlkIF0gKTtcblxuXHR9XG5cbn07XG5cbi8vIC0tLSBUb3AtbGV2ZWwgLS0tXG5cbi8vIFBhcnNlciAtIGJ1aWxkcyB1cCB0aGUgcHJvcGVydHkgdHJlZSBmcm9tIHRoZSBwYXRoIHN0cmluZ3NcblxudmFyIFJlUGF0aFBhcnQgPSAvKFtcXHdcXGRfXSspKFxcXSk/KFxcW3xcXC4pPy9nO1xuXG4vLyBleHRyYWN0c1xuLy8gXHQtIHRoZSBpZGVudGlmaWVyIChtZW1iZXIgbmFtZSBvciBhcnJheSBpbmRleClcbi8vICAtIGZvbGxvd2VkIGJ5IGFuIG9wdGlvbmFsIHJpZ2h0IGJyYWNrZXQgKGZvdW5kIHdoZW4gYXJyYXkgaW5kZXgpXG4vLyAgLSBmb2xsb3dlZCBieSBhbiBvcHRpb25hbCBsZWZ0IGJyYWNrZXQgb3IgZG90ICh0eXBlIG9mIHN1YnNjcmlwdClcbi8vXG4vLyBOb3RlOiBUaGVzZSBwb3J0aW9ucyBjYW4gYmUgcmVhZCBpbiBhIG5vbi1vdmVybGFwcGluZyBmYXNoaW9uIGFuZFxuLy8gYWxsb3cgc3RyYWlnaHRmb3J3YXJkIHBhcnNpbmcgb2YgdGhlIGhpZXJhcmNoeSB0aGF0IFdlYkdMIGVuY29kZXNcbi8vIGluIHRoZSB1bmlmb3JtIG5hbWVzLlxuXG5mdW5jdGlvbiBhZGRVbmlmb3JtKCBjb250YWluZXIsIHVuaWZvcm1PYmplY3QgKSB7XG5cblx0Y29udGFpbmVyLnNlcS5wdXNoKCB1bmlmb3JtT2JqZWN0ICk7XG5cdGNvbnRhaW5lci5tYXBbIHVuaWZvcm1PYmplY3QuaWQgXSA9IHVuaWZvcm1PYmplY3Q7XG5cbn1cblxuZnVuY3Rpb24gcGFyc2VVbmlmb3JtKCBhY3RpdmVJbmZvLCBhZGRyLCBjb250YWluZXIgKSB7XG5cblx0dmFyIHBhdGggPSBhY3RpdmVJbmZvLm5hbWUsXG5cdFx0cGF0aExlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG5cdC8vIHJlc2V0IFJlZ0V4cCBvYmplY3QsIGJlY2F1c2Ugb2YgdGhlIGVhcmx5IGV4aXQgb2YgYSBwcmV2aW91cyBydW5cblx0UmVQYXRoUGFydC5sYXN0SW5kZXggPSAwO1xuXG5cdGZvciAoIDsgOyApIHtcblxuXHRcdHZhciBtYXRjaCA9IFJlUGF0aFBhcnQuZXhlYyggcGF0aCApLFxuXHRcdFx0bWF0Y2hFbmQgPSBSZVBhdGhQYXJ0Lmxhc3RJbmRleCxcblxuXHRcdFx0aWQgPSBtYXRjaFsgMSBdLFxuXHRcdFx0aWRJc0luZGV4ID0gbWF0Y2hbIDIgXSA9PT0gJ10nLFxuXHRcdFx0c3Vic2NyaXB0ID0gbWF0Y2hbIDMgXTtcblxuXHRcdGlmICggaWRJc0luZGV4ICkgaWQgPSBpZCB8IDA7IC8vIGNvbnZlcnQgdG8gaW50ZWdlclxuXG5cdFx0aWYgKCBzdWJzY3JpcHQgPT09IHVuZGVmaW5lZCB8fCBzdWJzY3JpcHQgPT09ICdbJyAmJiBtYXRjaEVuZCArIDIgPT09IHBhdGhMZW5ndGggKSB7XG5cblx0XHRcdC8vIGJhcmUgbmFtZSBvciBcInB1cmVcIiBib3R0b20tbGV2ZWwgYXJyYXkgXCJbMF1cIiBzdWZmaXhcblxuXHRcdFx0YWRkVW5pZm9ybSggY29udGFpbmVyLCBzdWJzY3JpcHQgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdFx0bmV3IFNpbmdsZVVuaWZvcm0oIGlkLCBhY3RpdmVJbmZvLCBhZGRyICkgOlxuXHRcdFx0XHRcdG5ldyBQdXJlQXJyYXlVbmlmb3JtKCBpZCwgYWN0aXZlSW5mbywgYWRkciApICk7XG5cblx0XHRcdGJyZWFrO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gc3RlcCBpbnRvIGlubmVyIG5vZGUgLyBjcmVhdGUgaXQgaW4gY2FzZSBpdCBkb2Vzbid0IGV4aXN0XG5cblx0XHRcdHZhciBtYXAgPSBjb250YWluZXIubWFwLCBuZXh0ID0gbWFwWyBpZCBdO1xuXG5cdFx0XHRpZiAoIG5leHQgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRuZXh0ID0gbmV3IFN0cnVjdHVyZWRVbmlmb3JtKCBpZCApO1xuXHRcdFx0XHRhZGRVbmlmb3JtKCBjb250YWluZXIsIG5leHQgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRjb250YWluZXIgPSBuZXh0O1xuXG5cdFx0fVxuXG5cdH1cblxufVxuXG4vLyBSb290IENvbnRhaW5lclxuXG5mdW5jdGlvbiBXZWJHTFVuaWZvcm1zKCBnbCwgcHJvZ3JhbSwgcmVuZGVyZXIgKSB7XG5cblx0VW5pZm9ybUNvbnRhaW5lci5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuXG5cdHZhciBuID0gZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlciggcHJvZ3JhbSwgZ2wuQUNUSVZFX1VOSUZPUk1TICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbjsgKysgaSApIHtcblxuXHRcdHZhciBpbmZvID0gZ2wuZ2V0QWN0aXZlVW5pZm9ybSggcHJvZ3JhbSwgaSApLFxuXHRcdFx0cGF0aCA9IGluZm8ubmFtZSxcblx0XHRcdGFkZHIgPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sIHBhdGggKTtcblxuXHRcdHBhcnNlVW5pZm9ybSggaW5mbywgYWRkciwgdGhpcyApO1xuXG5cdH1cblxufVxuXG5XZWJHTFVuaWZvcm1zLnByb3RvdHlwZS5zZXRWYWx1ZSA9IGZ1bmN0aW9uICggZ2wsIG5hbWUsIHZhbHVlICkge1xuXG5cdHZhciB1ID0gdGhpcy5tYXBbIG5hbWUgXTtcblxuXHRpZiAoIHUgIT09IHVuZGVmaW5lZCApIHUuc2V0VmFsdWUoIGdsLCB2YWx1ZSwgdGhpcy5yZW5kZXJlciApO1xuXG59O1xuXG5XZWJHTFVuaWZvcm1zLnByb3RvdHlwZS5zZXRPcHRpb25hbCA9IGZ1bmN0aW9uICggZ2wsIG9iamVjdCwgbmFtZSApIHtcblxuXHR2YXIgdiA9IG9iamVjdFsgbmFtZSBdO1xuXG5cdGlmICggdiAhPT0gdW5kZWZpbmVkICkgdGhpcy5zZXRWYWx1ZSggZ2wsIG5hbWUsIHYgKTtcblxufTtcblxuXG4vLyBTdGF0aWMgaW50ZXJmYWNlXG5cbldlYkdMVW5pZm9ybXMudXBsb2FkID0gZnVuY3Rpb24gKCBnbCwgc2VxLCB2YWx1ZXMsIHJlbmRlcmVyICkge1xuXG5cdGZvciAoIHZhciBpID0gMCwgbiA9IHNlcS5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHR2YXIgdSA9IHNlcVsgaSBdLFxuXHRcdFx0diA9IHZhbHVlc1sgdS5pZCBdO1xuXG5cdFx0aWYgKCB2Lm5lZWRzVXBkYXRlICE9PSBmYWxzZSApIHtcblxuXHRcdFx0Ly8gbm90ZTogYWx3YXlzIHVwZGF0aW5nIHdoZW4gLm5lZWRzVXBkYXRlIGlzIHVuZGVmaW5lZFxuXHRcdFx0dS5zZXRWYWx1ZSggZ2wsIHYudmFsdWUsIHJlbmRlcmVyICk7XG5cblx0XHR9XG5cblx0fVxuXG59O1xuXG5XZWJHTFVuaWZvcm1zLnNlcVdpdGhWYWx1ZSA9IGZ1bmN0aW9uICggc2VxLCB2YWx1ZXMgKSB7XG5cblx0dmFyIHIgPSBbXTtcblxuXHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBzZXEubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0dmFyIHUgPSBzZXFbIGkgXTtcblx0XHRpZiAoIHUuaWQgaW4gdmFsdWVzICkgci5wdXNoKCB1ICk7XG5cblx0fVxuXG5cdHJldHVybiByO1xuXG59O1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxudmFyIENvbG9yS2V5d29yZHMgPSB7ICdhbGljZWJsdWUnOiAweEYwRjhGRiwgJ2FudGlxdWV3aGl0ZSc6IDB4RkFFQkQ3LCAnYXF1YSc6IDB4MDBGRkZGLCAnYXF1YW1hcmluZSc6IDB4N0ZGRkQ0LCAnYXp1cmUnOiAweEYwRkZGRixcblx0J2JlaWdlJzogMHhGNUY1REMsICdiaXNxdWUnOiAweEZGRTRDNCwgJ2JsYWNrJzogMHgwMDAwMDAsICdibGFuY2hlZGFsbW9uZCc6IDB4RkZFQkNELCAnYmx1ZSc6IDB4MDAwMEZGLCAnYmx1ZXZpb2xldCc6IDB4OEEyQkUyLFxuXHQnYnJvd24nOiAweEE1MkEyQSwgJ2J1cmx5d29vZCc6IDB4REVCODg3LCAnY2FkZXRibHVlJzogMHg1RjlFQTAsICdjaGFydHJldXNlJzogMHg3RkZGMDAsICdjaG9jb2xhdGUnOiAweEQyNjkxRSwgJ2NvcmFsJzogMHhGRjdGNTAsXG5cdCdjb3JuZmxvd2VyYmx1ZSc6IDB4NjQ5NUVELCAnY29ybnNpbGsnOiAweEZGRjhEQywgJ2NyaW1zb24nOiAweERDMTQzQywgJ2N5YW4nOiAweDAwRkZGRiwgJ2RhcmtibHVlJzogMHgwMDAwOEIsICdkYXJrY3lhbic6IDB4MDA4QjhCLFxuXHQnZGFya2dvbGRlbnJvZCc6IDB4Qjg4NjBCLCAnZGFya2dyYXknOiAweEE5QTlBOSwgJ2RhcmtncmVlbic6IDB4MDA2NDAwLCAnZGFya2dyZXknOiAweEE5QTlBOSwgJ2RhcmtraGFraSc6IDB4QkRCNzZCLCAnZGFya21hZ2VudGEnOiAweDhCMDA4Qixcblx0J2RhcmtvbGl2ZWdyZWVuJzogMHg1NTZCMkYsICdkYXJrb3JhbmdlJzogMHhGRjhDMDAsICdkYXJrb3JjaGlkJzogMHg5OTMyQ0MsICdkYXJrcmVkJzogMHg4QjAwMDAsICdkYXJrc2FsbW9uJzogMHhFOTk2N0EsICdkYXJrc2VhZ3JlZW4nOiAweDhGQkM4Rixcblx0J2RhcmtzbGF0ZWJsdWUnOiAweDQ4M0Q4QiwgJ2RhcmtzbGF0ZWdyYXknOiAweDJGNEY0RiwgJ2RhcmtzbGF0ZWdyZXknOiAweDJGNEY0RiwgJ2Rhcmt0dXJxdW9pc2UnOiAweDAwQ0VEMSwgJ2Rhcmt2aW9sZXQnOiAweDk0MDBEMyxcblx0J2RlZXBwaW5rJzogMHhGRjE0OTMsICdkZWVwc2t5Ymx1ZSc6IDB4MDBCRkZGLCAnZGltZ3JheSc6IDB4Njk2OTY5LCAnZGltZ3JleSc6IDB4Njk2OTY5LCAnZG9kZ2VyYmx1ZSc6IDB4MUU5MEZGLCAnZmlyZWJyaWNrJzogMHhCMjIyMjIsXG5cdCdmbG9yYWx3aGl0ZSc6IDB4RkZGQUYwLCAnZm9yZXN0Z3JlZW4nOiAweDIyOEIyMiwgJ2Z1Y2hzaWEnOiAweEZGMDBGRiwgJ2dhaW5zYm9ybyc6IDB4RENEQ0RDLCAnZ2hvc3R3aGl0ZSc6IDB4RjhGOEZGLCAnZ29sZCc6IDB4RkZENzAwLFxuXHQnZ29sZGVucm9kJzogMHhEQUE1MjAsICdncmF5JzogMHg4MDgwODAsICdncmVlbic6IDB4MDA4MDAwLCAnZ3JlZW55ZWxsb3cnOiAweEFERkYyRiwgJ2dyZXknOiAweDgwODA4MCwgJ2hvbmV5ZGV3JzogMHhGMEZGRjAsICdob3RwaW5rJzogMHhGRjY5QjQsXG5cdCdpbmRpYW5yZWQnOiAweENENUM1QywgJ2luZGlnbyc6IDB4NEIwMDgyLCAnaXZvcnknOiAweEZGRkZGMCwgJ2toYWtpJzogMHhGMEU2OEMsICdsYXZlbmRlcic6IDB4RTZFNkZBLCAnbGF2ZW5kZXJibHVzaCc6IDB4RkZGMEY1LCAnbGF3bmdyZWVuJzogMHg3Q0ZDMDAsXG5cdCdsZW1vbmNoaWZmb24nOiAweEZGRkFDRCwgJ2xpZ2h0Ymx1ZSc6IDB4QUREOEU2LCAnbGlnaHRjb3JhbCc6IDB4RjA4MDgwLCAnbGlnaHRjeWFuJzogMHhFMEZGRkYsICdsaWdodGdvbGRlbnJvZHllbGxvdyc6IDB4RkFGQUQyLCAnbGlnaHRncmF5JzogMHhEM0QzRDMsXG5cdCdsaWdodGdyZWVuJzogMHg5MEVFOTAsICdsaWdodGdyZXknOiAweEQzRDNEMywgJ2xpZ2h0cGluayc6IDB4RkZCNkMxLCAnbGlnaHRzYWxtb24nOiAweEZGQTA3QSwgJ2xpZ2h0c2VhZ3JlZW4nOiAweDIwQjJBQSwgJ2xpZ2h0c2t5Ymx1ZSc6IDB4ODdDRUZBLFxuXHQnbGlnaHRzbGF0ZWdyYXknOiAweDc3ODg5OSwgJ2xpZ2h0c2xhdGVncmV5JzogMHg3Nzg4OTksICdsaWdodHN0ZWVsYmx1ZSc6IDB4QjBDNERFLCAnbGlnaHR5ZWxsb3cnOiAweEZGRkZFMCwgJ2xpbWUnOiAweDAwRkYwMCwgJ2xpbWVncmVlbic6IDB4MzJDRDMyLFxuXHQnbGluZW4nOiAweEZBRjBFNiwgJ21hZ2VudGEnOiAweEZGMDBGRiwgJ21hcm9vbic6IDB4ODAwMDAwLCAnbWVkaXVtYXF1YW1hcmluZSc6IDB4NjZDREFBLCAnbWVkaXVtYmx1ZSc6IDB4MDAwMENELCAnbWVkaXVtb3JjaGlkJzogMHhCQTU1RDMsXG5cdCdtZWRpdW1wdXJwbGUnOiAweDkzNzBEQiwgJ21lZGl1bXNlYWdyZWVuJzogMHgzQ0IzNzEsICdtZWRpdW1zbGF0ZWJsdWUnOiAweDdCNjhFRSwgJ21lZGl1bXNwcmluZ2dyZWVuJzogMHgwMEZBOUEsICdtZWRpdW10dXJxdW9pc2UnOiAweDQ4RDFDQyxcblx0J21lZGl1bXZpb2xldHJlZCc6IDB4QzcxNTg1LCAnbWlkbmlnaHRibHVlJzogMHgxOTE5NzAsICdtaW50Y3JlYW0nOiAweEY1RkZGQSwgJ21pc3R5cm9zZSc6IDB4RkZFNEUxLCAnbW9jY2FzaW4nOiAweEZGRTRCNSwgJ25hdmFqb3doaXRlJzogMHhGRkRFQUQsXG5cdCduYXZ5JzogMHgwMDAwODAsICdvbGRsYWNlJzogMHhGREY1RTYsICdvbGl2ZSc6IDB4ODA4MDAwLCAnb2xpdmVkcmFiJzogMHg2QjhFMjMsICdvcmFuZ2UnOiAweEZGQTUwMCwgJ29yYW5nZXJlZCc6IDB4RkY0NTAwLCAnb3JjaGlkJzogMHhEQTcwRDYsXG5cdCdwYWxlZ29sZGVucm9kJzogMHhFRUU4QUEsICdwYWxlZ3JlZW4nOiAweDk4RkI5OCwgJ3BhbGV0dXJxdW9pc2UnOiAweEFGRUVFRSwgJ3BhbGV2aW9sZXRyZWQnOiAweERCNzA5MywgJ3BhcGF5YXdoaXAnOiAweEZGRUZENSwgJ3BlYWNocHVmZic6IDB4RkZEQUI5LFxuXHQncGVydSc6IDB4Q0Q4NTNGLCAncGluayc6IDB4RkZDMENCLCAncGx1bSc6IDB4RERBMERELCAncG93ZGVyYmx1ZSc6IDB4QjBFMEU2LCAncHVycGxlJzogMHg4MDAwODAsICdyZWQnOiAweEZGMDAwMCwgJ3Jvc3licm93bic6IDB4QkM4RjhGLFxuXHQncm95YWxibHVlJzogMHg0MTY5RTEsICdzYWRkbGVicm93bic6IDB4OEI0NTEzLCAnc2FsbW9uJzogMHhGQTgwNzIsICdzYW5keWJyb3duJzogMHhGNEE0NjAsICdzZWFncmVlbic6IDB4MkU4QjU3LCAnc2Vhc2hlbGwnOiAweEZGRjVFRSxcblx0J3NpZW5uYSc6IDB4QTA1MjJELCAnc2lsdmVyJzogMHhDMEMwQzAsICdza3libHVlJzogMHg4N0NFRUIsICdzbGF0ZWJsdWUnOiAweDZBNUFDRCwgJ3NsYXRlZ3JheSc6IDB4NzA4MDkwLCAnc2xhdGVncmV5JzogMHg3MDgwOTAsICdzbm93JzogMHhGRkZBRkEsXG5cdCdzcHJpbmdncmVlbic6IDB4MDBGRjdGLCAnc3RlZWxibHVlJzogMHg0NjgyQjQsICd0YW4nOiAweEQyQjQ4QywgJ3RlYWwnOiAweDAwODA4MCwgJ3RoaXN0bGUnOiAweEQ4QkZEOCwgJ3RvbWF0byc6IDB4RkY2MzQ3LCAndHVycXVvaXNlJzogMHg0MEUwRDAsXG5cdCd2aW9sZXQnOiAweEVFODJFRSwgJ3doZWF0JzogMHhGNURFQjMsICd3aGl0ZSc6IDB4RkZGRkZGLCAnd2hpdGVzbW9rZSc6IDB4RjVGNUY1LCAneWVsbG93JzogMHhGRkZGMDAsICd5ZWxsb3dncmVlbic6IDB4OUFDRDMyIH07XG5cbmZ1bmN0aW9uIENvbG9yKCByLCBnLCBiICkge1xuXG5cdGlmICggZyA9PT0gdW5kZWZpbmVkICYmIGIgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdC8vIHIgaXMgVEhSRUUuQ29sb3IsIGhleCBvciBzdHJpbmdcblx0XHRyZXR1cm4gdGhpcy5zZXQoIHIgKTtcblxuXHR9XG5cblx0cmV0dXJuIHRoaXMuc2V0UkdCKCByLCBnLCBiICk7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQ29sb3IucHJvdG90eXBlLCB7XG5cblx0aXNDb2xvcjogdHJ1ZSxcblxuXHRyOiAxLCBnOiAxLCBiOiAxLFxuXG5cdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdGlmICggdmFsdWUgJiYgdmFsdWUuaXNDb2xvciApIHtcblxuXHRcdFx0dGhpcy5jb3B5KCB2YWx1ZSApO1xuXG5cdFx0fSBlbHNlIGlmICggdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyApIHtcblxuXHRcdFx0dGhpcy5zZXRIZXgoIHZhbHVlICk7XG5cblx0XHR9IGVsc2UgaWYgKCB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICkge1xuXG5cdFx0XHR0aGlzLnNldFN0eWxlKCB2YWx1ZSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRTY2FsYXI6IGZ1bmN0aW9uICggc2NhbGFyICkge1xuXG5cdFx0dGhpcy5yID0gc2NhbGFyO1xuXHRcdHRoaXMuZyA9IHNjYWxhcjtcblx0XHR0aGlzLmIgPSBzY2FsYXI7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEhleDogZnVuY3Rpb24gKCBoZXggKSB7XG5cblx0XHRoZXggPSBNYXRoLmZsb29yKCBoZXggKTtcblxuXHRcdHRoaXMuciA9ICggaGV4ID4+IDE2ICYgMjU1ICkgLyAyNTU7XG5cdFx0dGhpcy5nID0gKCBoZXggPj4gOCAmIDI1NSApIC8gMjU1O1xuXHRcdHRoaXMuYiA9ICggaGV4ICYgMjU1ICkgLyAyNTU7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFJHQjogZnVuY3Rpb24gKCByLCBnLCBiICkge1xuXG5cdFx0dGhpcy5yID0gcjtcblx0XHR0aGlzLmcgPSBnO1xuXHRcdHRoaXMuYiA9IGI7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEhTTDogZnVuY3Rpb24gKCkge1xuXG5cdFx0ZnVuY3Rpb24gaHVlMnJnYiggcCwgcSwgdCApIHtcblxuXHRcdFx0aWYgKCB0IDwgMCApIHQgKz0gMTtcblx0XHRcdGlmICggdCA+IDEgKSB0IC09IDE7XG5cdFx0XHRpZiAoIHQgPCAxIC8gNiApIHJldHVybiBwICsgKCBxIC0gcCApICogNiAqIHQ7XG5cdFx0XHRpZiAoIHQgPCAxIC8gMiApIHJldHVybiBxO1xuXHRcdFx0aWYgKCB0IDwgMiAvIDMgKSByZXR1cm4gcCArICggcSAtIHAgKSAqIDYgKiAoIDIgLyAzIC0gdCApO1xuXHRcdFx0cmV0dXJuIHA7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gc2V0SFNMKCBoLCBzLCBsICkge1xuXG5cdFx0XHQvLyBoLHMsbCByYW5nZXMgYXJlIGluIDAuMCAtIDEuMFxuXHRcdFx0aCA9IF9NYXRoLmV1Y2xpZGVhbk1vZHVsbyggaCwgMSApO1xuXHRcdFx0cyA9IF9NYXRoLmNsYW1wKCBzLCAwLCAxICk7XG5cdFx0XHRsID0gX01hdGguY2xhbXAoIGwsIDAsIDEgKTtcblxuXHRcdFx0aWYgKCBzID09PSAwICkge1xuXG5cdFx0XHRcdHRoaXMuciA9IHRoaXMuZyA9IHRoaXMuYiA9IGw7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dmFyIHAgPSBsIDw9IDAuNSA/IGwgKiAoIDEgKyBzICkgOiBsICsgcyAtICggbCAqIHMgKTtcblx0XHRcdFx0dmFyIHEgPSAoIDIgKiBsICkgLSBwO1xuXG5cdFx0XHRcdHRoaXMuciA9IGh1ZTJyZ2IoIHEsIHAsIGggKyAxIC8gMyApO1xuXHRcdFx0XHR0aGlzLmcgPSBodWUycmdiKCBxLCBwLCBoICk7XG5cdFx0XHRcdHRoaXMuYiA9IGh1ZTJyZ2IoIHEsIHAsIGggLSAxIC8gMyApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0c2V0U3R5bGU6IGZ1bmN0aW9uICggc3R5bGUgKSB7XG5cblx0XHRmdW5jdGlvbiBoYW5kbGVBbHBoYSggc3RyaW5nICkge1xuXG5cdFx0XHRpZiAoIHN0cmluZyA9PT0gdW5kZWZpbmVkICkgcmV0dXJuO1xuXG5cdFx0XHRpZiAoIHBhcnNlRmxvYXQoIHN0cmluZyApIDwgMSApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Db2xvcjogQWxwaGEgY29tcG9uZW50IG9mICcgKyBzdHlsZSArICcgd2lsbCBiZSBpZ25vcmVkLicgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cblx0XHR2YXIgbTtcblxuXHRcdGlmICggbSA9IC9eKCg/OnJnYnxoc2wpYT8pXFwoXFxzKihbXlxcKV0qKVxcKS8uZXhlYyggc3R5bGUgKSApIHtcblxuXHRcdFx0Ly8gcmdiIC8gaHNsXG5cblx0XHRcdHZhciBjb2xvcjtcblx0XHRcdHZhciBuYW1lID0gbVsgMSBdO1xuXHRcdFx0dmFyIGNvbXBvbmVudHMgPSBtWyAyIF07XG5cblx0XHRcdHN3aXRjaCAoIG5hbWUgKSB7XG5cblx0XHRcdFx0Y2FzZSAncmdiJzpcblx0XHRcdFx0Y2FzZSAncmdiYSc6XG5cblx0XHRcdFx0XHRpZiAoIGNvbG9yID0gL14oXFxkKylcXHMqLFxccyooXFxkKylcXHMqLFxccyooXFxkKylcXHMqKCxcXHMqKFswLTldKlxcLj9bMC05XSspXFxzKik/JC8uZXhlYyggY29tcG9uZW50cyApICkge1xuXG5cdFx0XHRcdFx0XHQvLyByZ2IoMjU1LDAsMCkgcmdiYSgyNTUsMCwwLDAuNSlcblx0XHRcdFx0XHRcdHRoaXMuciA9IE1hdGgubWluKCAyNTUsIHBhcnNlSW50KCBjb2xvclsgMSBdLCAxMCApICkgLyAyNTU7XG5cdFx0XHRcdFx0XHR0aGlzLmcgPSBNYXRoLm1pbiggMjU1LCBwYXJzZUludCggY29sb3JbIDIgXSwgMTAgKSApIC8gMjU1O1xuXHRcdFx0XHRcdFx0dGhpcy5iID0gTWF0aC5taW4oIDI1NSwgcGFyc2VJbnQoIGNvbG9yWyAzIF0sIDEwICkgKSAvIDI1NTtcblxuXHRcdFx0XHRcdFx0aGFuZGxlQWxwaGEoIGNvbG9yWyA1IF0gKTtcblxuXHRcdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGNvbG9yID0gL14oXFxkKylcXCVcXHMqLFxccyooXFxkKylcXCVcXHMqLFxccyooXFxkKylcXCVcXHMqKCxcXHMqKFswLTldKlxcLj9bMC05XSspXFxzKik/JC8uZXhlYyggY29tcG9uZW50cyApICkge1xuXG5cdFx0XHRcdFx0XHQvLyByZ2IoMTAwJSwwJSwwJSkgcmdiYSgxMDAlLDAlLDAlLDAuNSlcblx0XHRcdFx0XHRcdHRoaXMuciA9IE1hdGgubWluKCAxMDAsIHBhcnNlSW50KCBjb2xvclsgMSBdLCAxMCApICkgLyAxMDA7XG5cdFx0XHRcdFx0XHR0aGlzLmcgPSBNYXRoLm1pbiggMTAwLCBwYXJzZUludCggY29sb3JbIDIgXSwgMTAgKSApIC8gMTAwO1xuXHRcdFx0XHRcdFx0dGhpcy5iID0gTWF0aC5taW4oIDEwMCwgcGFyc2VJbnQoIGNvbG9yWyAzIF0sIDEwICkgKSAvIDEwMDtcblxuXHRcdFx0XHRcdFx0aGFuZGxlQWxwaGEoIGNvbG9yWyA1IF0gKTtcblxuXHRcdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdoc2wnOlxuXHRcdFx0XHRjYXNlICdoc2xhJzpcblxuXHRcdFx0XHRcdGlmICggY29sb3IgPSAvXihbMC05XSpcXC4/WzAtOV0rKVxccyosXFxzKihcXGQrKVxcJVxccyosXFxzKihcXGQrKVxcJVxccyooLFxccyooWzAtOV0qXFwuP1swLTldKylcXHMqKT8kLy5leGVjKCBjb21wb25lbnRzICkgKSB7XG5cblx0XHRcdFx0XHRcdC8vIGhzbCgxMjAsNTAlLDUwJSkgaHNsYSgxMjAsNTAlLDUwJSwwLjUpXG5cdFx0XHRcdFx0XHR2YXIgaCA9IHBhcnNlRmxvYXQoIGNvbG9yWyAxIF0gKSAvIDM2MDtcblx0XHRcdFx0XHRcdHZhciBzID0gcGFyc2VJbnQoIGNvbG9yWyAyIF0sIDEwICkgLyAxMDA7XG5cdFx0XHRcdFx0XHR2YXIgbCA9IHBhcnNlSW50KCBjb2xvclsgMyBdLCAxMCApIC8gMTAwO1xuXG5cdFx0XHRcdFx0XHRoYW5kbGVBbHBoYSggY29sb3JbIDUgXSApO1xuXG5cdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5zZXRIU0woIGgsIHMsIGwgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBtID0gL15cXCMoW0EtRmEtZjAtOV0rKSQvLmV4ZWMoIHN0eWxlICkgKSB7XG5cblx0XHRcdC8vIGhleCBjb2xvclxuXG5cdFx0XHR2YXIgaGV4ID0gbVsgMSBdO1xuXHRcdFx0dmFyIHNpemUgPSBoZXgubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHNpemUgPT09IDMgKSB7XG5cblx0XHRcdFx0Ly8gI2ZmMFxuXHRcdFx0XHR0aGlzLnIgPSBwYXJzZUludCggaGV4LmNoYXJBdCggMCApICsgaGV4LmNoYXJBdCggMCApLCAxNiApIC8gMjU1O1xuXHRcdFx0XHR0aGlzLmcgPSBwYXJzZUludCggaGV4LmNoYXJBdCggMSApICsgaGV4LmNoYXJBdCggMSApLCAxNiApIC8gMjU1O1xuXHRcdFx0XHR0aGlzLmIgPSBwYXJzZUludCggaGV4LmNoYXJBdCggMiApICsgaGV4LmNoYXJBdCggMiApLCAxNiApIC8gMjU1O1xuXG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBzaXplID09PSA2ICkge1xuXG5cdFx0XHRcdC8vICNmZjAwMDBcblx0XHRcdFx0dGhpcy5yID0gcGFyc2VJbnQoIGhleC5jaGFyQXQoIDAgKSArIGhleC5jaGFyQXQoIDEgKSwgMTYgKSAvIDI1NTtcblx0XHRcdFx0dGhpcy5nID0gcGFyc2VJbnQoIGhleC5jaGFyQXQoIDIgKSArIGhleC5jaGFyQXQoIDMgKSwgMTYgKSAvIDI1NTtcblx0XHRcdFx0dGhpcy5iID0gcGFyc2VJbnQoIGhleC5jaGFyQXQoIDQgKSArIGhleC5jaGFyQXQoIDUgKSwgMTYgKSAvIDI1NTtcblxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aWYgKCBzdHlsZSAmJiBzdHlsZS5sZW5ndGggPiAwICkge1xuXG5cdFx0XHQvLyBjb2xvciBrZXl3b3Jkc1xuXHRcdFx0dmFyIGhleCA9IENvbG9yS2V5d29yZHNbIHN0eWxlIF07XG5cblx0XHRcdGlmICggaGV4ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gcmVkXG5cdFx0XHRcdHRoaXMuc2V0SGV4KCBoZXggKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyB1bmtub3duIGNvbG9yXG5cdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkNvbG9yOiBVbmtub3duIGNvbG9yICcgKyBzdHlsZSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoIHRoaXMuciwgdGhpcy5nLCB0aGlzLmIgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggY29sb3IgKSB7XG5cblx0XHR0aGlzLnIgPSBjb2xvci5yO1xuXHRcdHRoaXMuZyA9IGNvbG9yLmc7XG5cdFx0dGhpcy5iID0gY29sb3IuYjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weUdhbW1hVG9MaW5lYXI6IGZ1bmN0aW9uICggY29sb3IsIGdhbW1hRmFjdG9yICkge1xuXG5cdFx0aWYgKCBnYW1tYUZhY3RvciA9PT0gdW5kZWZpbmVkICkgZ2FtbWFGYWN0b3IgPSAyLjA7XG5cblx0XHR0aGlzLnIgPSBNYXRoLnBvdyggY29sb3IuciwgZ2FtbWFGYWN0b3IgKTtcblx0XHR0aGlzLmcgPSBNYXRoLnBvdyggY29sb3IuZywgZ2FtbWFGYWN0b3IgKTtcblx0XHR0aGlzLmIgPSBNYXRoLnBvdyggY29sb3IuYiwgZ2FtbWFGYWN0b3IgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weUxpbmVhclRvR2FtbWE6IGZ1bmN0aW9uICggY29sb3IsIGdhbW1hRmFjdG9yICkge1xuXG5cdFx0aWYgKCBnYW1tYUZhY3RvciA9PT0gdW5kZWZpbmVkICkgZ2FtbWFGYWN0b3IgPSAyLjA7XG5cblx0XHR2YXIgc2FmZUludmVyc2UgPSAoIGdhbW1hRmFjdG9yID4gMCApID8gKCAxLjAgLyBnYW1tYUZhY3RvciApIDogMS4wO1xuXG5cdFx0dGhpcy5yID0gTWF0aC5wb3coIGNvbG9yLnIsIHNhZmVJbnZlcnNlICk7XG5cdFx0dGhpcy5nID0gTWF0aC5wb3coIGNvbG9yLmcsIHNhZmVJbnZlcnNlICk7XG5cdFx0dGhpcy5iID0gTWF0aC5wb3coIGNvbG9yLmIsIHNhZmVJbnZlcnNlICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvbnZlcnRHYW1tYVRvTGluZWFyOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgciA9IHRoaXMuciwgZyA9IHRoaXMuZywgYiA9IHRoaXMuYjtcblxuXHRcdHRoaXMuciA9IHIgKiByO1xuXHRcdHRoaXMuZyA9IGcgKiBnO1xuXHRcdHRoaXMuYiA9IGIgKiBiO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjb252ZXJ0TGluZWFyVG9HYW1tYTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5yID0gTWF0aC5zcXJ0KCB0aGlzLnIgKTtcblx0XHR0aGlzLmcgPSBNYXRoLnNxcnQoIHRoaXMuZyApO1xuXHRcdHRoaXMuYiA9IE1hdGguc3FydCggdGhpcy5iICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldEhleDogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuICggdGhpcy5yICogMjU1ICkgPDwgMTYgXiAoIHRoaXMuZyAqIDI1NSApIDw8IDggXiAoIHRoaXMuYiAqIDI1NSApIDw8IDA7XG5cblx0fSxcblxuXHRnZXRIZXhTdHJpbmc6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiAoICcwMDAwMDAnICsgdGhpcy5nZXRIZXgoKS50b1N0cmluZyggMTYgKSApLnNsaWNlKCAtIDYgKTtcblxuXHR9LFxuXG5cdGdldEhTTDogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdC8vIGgscyxsIHJhbmdlcyBhcmUgaW4gMC4wIC0gMS4wXG5cblx0XHR2YXIgaHNsID0gb3B0aW9uYWxUYXJnZXQgfHwgeyBoOiAwLCBzOiAwLCBsOiAwIH07XG5cblx0XHR2YXIgciA9IHRoaXMuciwgZyA9IHRoaXMuZywgYiA9IHRoaXMuYjtcblxuXHRcdHZhciBtYXggPSBNYXRoLm1heCggciwgZywgYiApO1xuXHRcdHZhciBtaW4gPSBNYXRoLm1pbiggciwgZywgYiApO1xuXG5cdFx0dmFyIGh1ZSwgc2F0dXJhdGlvbjtcblx0XHR2YXIgbGlnaHRuZXNzID0gKCBtaW4gKyBtYXggKSAvIDIuMDtcblxuXHRcdGlmICggbWluID09PSBtYXggKSB7XG5cblx0XHRcdGh1ZSA9IDA7XG5cdFx0XHRzYXR1cmF0aW9uID0gMDtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHZhciBkZWx0YSA9IG1heCAtIG1pbjtcblxuXHRcdFx0c2F0dXJhdGlvbiA9IGxpZ2h0bmVzcyA8PSAwLjUgPyBkZWx0YSAvICggbWF4ICsgbWluICkgOiBkZWx0YSAvICggMiAtIG1heCAtIG1pbiApO1xuXG5cdFx0XHRzd2l0Y2ggKCBtYXggKSB7XG5cblx0XHRcdFx0Y2FzZSByOiBodWUgPSAoIGcgLSBiICkgLyBkZWx0YSArICggZyA8IGIgPyA2IDogMCApOyBicmVhaztcblx0XHRcdFx0Y2FzZSBnOiBodWUgPSAoIGIgLSByICkgLyBkZWx0YSArIDI7IGJyZWFrO1xuXHRcdFx0XHRjYXNlIGI6IGh1ZSA9ICggciAtIGcgKSAvIGRlbHRhICsgNDsgYnJlYWs7XG5cblx0XHRcdH1cblxuXHRcdFx0aHVlIC89IDY7XG5cblx0XHR9XG5cblx0XHRoc2wuaCA9IGh1ZTtcblx0XHRoc2wucyA9IHNhdHVyYXRpb247XG5cdFx0aHNsLmwgPSBsaWdodG5lc3M7XG5cblx0XHRyZXR1cm4gaHNsO1xuXG5cdH0sXG5cblx0Z2V0U3R5bGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiAncmdiKCcgKyAoICggdGhpcy5yICogMjU1ICkgfCAwICkgKyAnLCcgKyAoICggdGhpcy5nICogMjU1ICkgfCAwICkgKyAnLCcgKyAoICggdGhpcy5iICogMjU1ICkgfCAwICkgKyAnKSc7XG5cblx0fSxcblxuXHRvZmZzZXRIU0w6IGZ1bmN0aW9uICggaCwgcywgbCApIHtcblxuXHRcdHZhciBoc2wgPSB0aGlzLmdldEhTTCgpO1xuXG5cdFx0aHNsLmggKz0gaDsgaHNsLnMgKz0gczsgaHNsLmwgKz0gbDtcblxuXHRcdHRoaXMuc2V0SFNMKCBoc2wuaCwgaHNsLnMsIGhzbC5sICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24gKCBjb2xvciApIHtcblxuXHRcdHRoaXMuciArPSBjb2xvci5yO1xuXHRcdHRoaXMuZyArPSBjb2xvci5nO1xuXHRcdHRoaXMuYiArPSBjb2xvci5iO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRhZGRDb2xvcnM6IGZ1bmN0aW9uICggY29sb3IxLCBjb2xvcjIgKSB7XG5cblx0XHR0aGlzLnIgPSBjb2xvcjEuciArIGNvbG9yMi5yO1xuXHRcdHRoaXMuZyA9IGNvbG9yMS5nICsgY29sb3IyLmc7XG5cdFx0dGhpcy5iID0gY29sb3IxLmIgKyBjb2xvcjIuYjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YWRkU2NhbGFyOiBmdW5jdGlvbiAoIHMgKSB7XG5cblx0XHR0aGlzLnIgKz0gcztcblx0XHR0aGlzLmcgKz0gcztcblx0XHR0aGlzLmIgKz0gcztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c3ViOiBmdW5jdGlvbiggY29sb3IgKSB7XG5cblx0XHR0aGlzLnIgPSBNYXRoLm1heCggMCwgdGhpcy5yIC0gY29sb3IuciApO1xuXHRcdHRoaXMuZyA9IE1hdGgubWF4KCAwLCB0aGlzLmcgLSBjb2xvci5nICk7XG5cdFx0dGhpcy5iID0gTWF0aC5tYXgoIDAsIHRoaXMuYiAtIGNvbG9yLmIgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bXVsdGlwbHk6IGZ1bmN0aW9uICggY29sb3IgKSB7XG5cblx0XHR0aGlzLnIgKj0gY29sb3Iucjtcblx0XHR0aGlzLmcgKj0gY29sb3IuZztcblx0XHR0aGlzLmIgKj0gY29sb3IuYjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bXVsdGlwbHlTY2FsYXI6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHRoaXMuciAqPSBzO1xuXHRcdHRoaXMuZyAqPSBzO1xuXHRcdHRoaXMuYiAqPSBzO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRsZXJwOiBmdW5jdGlvbiAoIGNvbG9yLCBhbHBoYSApIHtcblxuXHRcdHRoaXMuciArPSAoIGNvbG9yLnIgLSB0aGlzLnIgKSAqIGFscGhhO1xuXHRcdHRoaXMuZyArPSAoIGNvbG9yLmcgLSB0aGlzLmcgKSAqIGFscGhhO1xuXHRcdHRoaXMuYiArPSAoIGNvbG9yLmIgLSB0aGlzLmIgKSAqIGFscGhhO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRlcXVhbHM6IGZ1bmN0aW9uICggYyApIHtcblxuXHRcdHJldHVybiAoIGMuciA9PT0gdGhpcy5yICkgJiYgKCBjLmcgPT09IHRoaXMuZyApICYmICggYy5iID09PSB0aGlzLmIgKTtcblxuXHR9LFxuXG5cdGZyb21BcnJheTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIG9mZnNldCA9IDA7XG5cblx0XHR0aGlzLnIgPSBhcnJheVsgb2Zmc2V0IF07XG5cdFx0dGhpcy5nID0gYXJyYXlbIG9mZnNldCArIDEgXTtcblx0XHR0aGlzLmIgPSBhcnJheVsgb2Zmc2V0ICsgMiBdO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR0b0FycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIGFycmF5ID09PSB1bmRlZmluZWQgKSBhcnJheSA9IFtdO1xuXHRcdGlmICggb2Zmc2V0ID09PSB1bmRlZmluZWQgKSBvZmZzZXQgPSAwO1xuXG5cdFx0YXJyYXlbIG9mZnNldCBdID0gdGhpcy5yO1xuXHRcdGFycmF5WyBvZmZzZXQgKyAxIF0gPSB0aGlzLmc7XG5cdFx0YXJyYXlbIG9mZnNldCArIDIgXSA9IHRoaXMuYjtcblxuXHRcdHJldHVybiBhcnJheTtcblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0SGV4KCk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogVW5pZm9ybXMgbGlicmFyeSBmb3Igc2hhcmVkIHdlYmdsIHNoYWRlcnNcbiAqL1xuXG52YXIgVW5pZm9ybXNMaWIgPSB7XG5cblx0Y29tbW9uOiB7XG5cblx0XHRkaWZmdXNlOiB7IHZhbHVlOiBuZXcgQ29sb3IoIDB4ZWVlZWVlICkgfSxcblx0XHRvcGFjaXR5OiB7IHZhbHVlOiAxLjAgfSxcblxuXHRcdG1hcDogeyB2YWx1ZTogbnVsbCB9LFxuXHRcdG9mZnNldFJlcGVhdDogeyB2YWx1ZTogbmV3IFZlY3RvcjQoIDAsIDAsIDEsIDEgKSB9LFxuXG5cdFx0c3BlY3VsYXJNYXA6IHsgdmFsdWU6IG51bGwgfSxcblx0XHRhbHBoYU1hcDogeyB2YWx1ZTogbnVsbCB9LFxuXG5cdFx0ZW52TWFwOiB7IHZhbHVlOiBudWxsIH0sXG5cdFx0ZmxpcEVudk1hcDogeyB2YWx1ZTogLSAxIH0sXG5cdFx0cmVmbGVjdGl2aXR5OiB7IHZhbHVlOiAxLjAgfSxcblx0XHRyZWZyYWN0aW9uUmF0aW86IHsgdmFsdWU6IDAuOTggfVxuXG5cdH0sXG5cblx0YW9tYXA6IHtcblxuXHRcdGFvTWFwOiB7IHZhbHVlOiBudWxsIH0sXG5cdFx0YW9NYXBJbnRlbnNpdHk6IHsgdmFsdWU6IDEgfVxuXG5cdH0sXG5cblx0bGlnaHRtYXA6IHtcblxuXHRcdGxpZ2h0TWFwOiB7IHZhbHVlOiBudWxsIH0sXG5cdFx0bGlnaHRNYXBJbnRlbnNpdHk6IHsgdmFsdWU6IDEgfVxuXG5cdH0sXG5cblx0ZW1pc3NpdmVtYXA6IHtcblxuXHRcdGVtaXNzaXZlTWFwOiB7IHZhbHVlOiBudWxsIH1cblxuXHR9LFxuXG5cdGJ1bXBtYXA6IHtcblxuXHRcdGJ1bXBNYXA6IHsgdmFsdWU6IG51bGwgfSxcblx0XHRidW1wU2NhbGU6IHsgdmFsdWU6IDEgfVxuXG5cdH0sXG5cblx0bm9ybWFsbWFwOiB7XG5cblx0XHRub3JtYWxNYXA6IHsgdmFsdWU6IG51bGwgfSxcblx0XHRub3JtYWxTY2FsZTogeyB2YWx1ZTogbmV3IFZlY3RvcjIoIDEsIDEgKSB9XG5cblx0fSxcblxuXHRkaXNwbGFjZW1lbnRtYXA6IHtcblxuXHRcdGRpc3BsYWNlbWVudE1hcDogeyB2YWx1ZTogbnVsbCB9LFxuXHRcdGRpc3BsYWNlbWVudFNjYWxlOiB7IHZhbHVlOiAxIH0sXG5cdFx0ZGlzcGxhY2VtZW50QmlhczogeyB2YWx1ZTogMCB9XG5cblx0fSxcblxuXHRyb3VnaG5lc3NtYXA6IHtcblxuXHRcdHJvdWdobmVzc01hcDogeyB2YWx1ZTogbnVsbCB9XG5cblx0fSxcblxuXHRtZXRhbG5lc3NtYXA6IHtcblxuXHRcdG1ldGFsbmVzc01hcDogeyB2YWx1ZTogbnVsbCB9XG5cblx0fSxcblxuXHRncmFkaWVudG1hcDoge1xuXG5cdFx0Z3JhZGllbnRNYXA6IHsgdmFsdWU6IG51bGwgfVxuXG5cdH0sXG5cblx0Zm9nOiB7XG5cblx0XHRmb2dEZW5zaXR5OiB7IHZhbHVlOiAwLjAwMDI1IH0sXG5cdFx0Zm9nTmVhcjogeyB2YWx1ZTogMSB9LFxuXHRcdGZvZ0ZhcjogeyB2YWx1ZTogMjAwMCB9LFxuXHRcdGZvZ0NvbG9yOiB7IHZhbHVlOiBuZXcgQ29sb3IoIDB4ZmZmZmZmICkgfVxuXG5cdH0sXG5cblx0bGlnaHRzOiB7XG5cblx0XHRhbWJpZW50TGlnaHRDb2xvcjogeyB2YWx1ZTogW10gfSxcblxuXHRcdGRpcmVjdGlvbmFsTGlnaHRzOiB7IHZhbHVlOiBbXSwgcHJvcGVydGllczoge1xuXHRcdFx0ZGlyZWN0aW9uOiB7fSxcblx0XHRcdGNvbG9yOiB7fSxcblxuXHRcdFx0c2hhZG93OiB7fSxcblx0XHRcdHNoYWRvd0JpYXM6IHt9LFxuXHRcdFx0c2hhZG93UmFkaXVzOiB7fSxcblx0XHRcdHNoYWRvd01hcFNpemU6IHt9XG5cdFx0fSB9LFxuXG5cdFx0ZGlyZWN0aW9uYWxTaGFkb3dNYXA6IHsgdmFsdWU6IFtdIH0sXG5cdFx0ZGlyZWN0aW9uYWxTaGFkb3dNYXRyaXg6IHsgdmFsdWU6IFtdIH0sXG5cblx0XHRzcG90TGlnaHRzOiB7IHZhbHVlOiBbXSwgcHJvcGVydGllczoge1xuXHRcdFx0Y29sb3I6IHt9LFxuXHRcdFx0cG9zaXRpb246IHt9LFxuXHRcdFx0ZGlyZWN0aW9uOiB7fSxcblx0XHRcdGRpc3RhbmNlOiB7fSxcblx0XHRcdGNvbmVDb3M6IHt9LFxuXHRcdFx0cGVudW1icmFDb3M6IHt9LFxuXHRcdFx0ZGVjYXk6IHt9LFxuXG5cdFx0XHRzaGFkb3c6IHt9LFxuXHRcdFx0c2hhZG93Qmlhczoge30sXG5cdFx0XHRzaGFkb3dSYWRpdXM6IHt9LFxuXHRcdFx0c2hhZG93TWFwU2l6ZToge31cblx0XHR9IH0sXG5cblx0XHRzcG90U2hhZG93TWFwOiB7IHZhbHVlOiBbXSB9LFxuXHRcdHNwb3RTaGFkb3dNYXRyaXg6IHsgdmFsdWU6IFtdIH0sXG5cblx0XHRwb2ludExpZ2h0czogeyB2YWx1ZTogW10sIHByb3BlcnRpZXM6IHtcblx0XHRcdGNvbG9yOiB7fSxcblx0XHRcdHBvc2l0aW9uOiB7fSxcblx0XHRcdGRlY2F5OiB7fSxcblx0XHRcdGRpc3RhbmNlOiB7fSxcblxuXHRcdFx0c2hhZG93OiB7fSxcblx0XHRcdHNoYWRvd0JpYXM6IHt9LFxuXHRcdFx0c2hhZG93UmFkaXVzOiB7fSxcblx0XHRcdHNoYWRvd01hcFNpemU6IHt9XG5cdFx0fSB9LFxuXG5cdFx0cG9pbnRTaGFkb3dNYXA6IHsgdmFsdWU6IFtdIH0sXG5cdFx0cG9pbnRTaGFkb3dNYXRyaXg6IHsgdmFsdWU6IFtdIH0sXG5cblx0XHRoZW1pc3BoZXJlTGlnaHRzOiB7IHZhbHVlOiBbXSwgcHJvcGVydGllczoge1xuXHRcdFx0ZGlyZWN0aW9uOiB7fSxcblx0XHRcdHNreUNvbG9yOiB7fSxcblx0XHRcdGdyb3VuZENvbG9yOiB7fVxuXHRcdH0gfSxcblxuXHRcdC8vIFRPRE8gKGFiZWxuYXRpb24pOiBSZWN0QXJlYUxpZ2h0IEJSREYgZGF0YSBuZWVkcyB0byBiZSBtb3ZlZCBmcm9tIGV4YW1wbGUgdG8gbWFpbiBzcmNcblx0XHRyZWN0QXJlYUxpZ2h0czogeyB2YWx1ZTogW10sIHByb3BlcnRpZXM6IHtcblx0XHRcdGNvbG9yOiB7fSxcblx0XHRcdHBvc2l0aW9uOiB7fSxcblx0XHRcdHdpZHRoOiB7fSxcblx0XHRcdGhlaWdodDoge31cblx0XHR9IH1cblxuXHR9LFxuXG5cdHBvaW50czoge1xuXG5cdFx0ZGlmZnVzZTogeyB2YWx1ZTogbmV3IENvbG9yKCAweGVlZWVlZSApIH0sXG5cdFx0b3BhY2l0eTogeyB2YWx1ZTogMS4wIH0sXG5cdFx0c2l6ZTogeyB2YWx1ZTogMS4wIH0sXG5cdFx0c2NhbGU6IHsgdmFsdWU6IDEuMCB9LFxuXHRcdG1hcDogeyB2YWx1ZTogbnVsbCB9LFxuXHRcdG9mZnNldFJlcGVhdDogeyB2YWx1ZTogbmV3IFZlY3RvcjQoIDAsIDAsIDEsIDEgKSB9XG5cblx0fVxuXG59O1xuXG4vKipcbiAqIFVuaWZvcm0gVXRpbGl0aWVzXG4gKi9cblxudmFyIFVuaWZvcm1zVXRpbHMgPSB7XG5cblx0bWVyZ2U6IGZ1bmN0aW9uICggdW5pZm9ybXMgKSB7XG5cblx0XHR2YXIgbWVyZ2VkID0ge307XG5cblx0XHRmb3IgKCB2YXIgdSA9IDA7IHUgPCB1bmlmb3Jtcy5sZW5ndGg7IHUgKysgKSB7XG5cblx0XHRcdHZhciB0bXAgPSB0aGlzLmNsb25lKCB1bmlmb3Jtc1sgdSBdICk7XG5cblx0XHRcdGZvciAoIHZhciBwIGluIHRtcCApIHtcblxuXHRcdFx0XHRtZXJnZWRbIHAgXSA9IHRtcFsgcCBdO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gbWVyZ2VkO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICggdW5pZm9ybXNfc3JjICkge1xuXG5cdFx0dmFyIHVuaWZvcm1zX2RzdCA9IHt9O1xuXG5cdFx0Zm9yICggdmFyIHUgaW4gdW5pZm9ybXNfc3JjICkge1xuXG5cdFx0XHR1bmlmb3Jtc19kc3RbIHUgXSA9IHt9O1xuXG5cdFx0XHRmb3IgKCB2YXIgcCBpbiB1bmlmb3Jtc19zcmNbIHUgXSApIHtcblxuXHRcdFx0XHR2YXIgcGFyYW1ldGVyX3NyYyA9IHVuaWZvcm1zX3NyY1sgdSBdWyBwIF07XG5cblx0XHRcdFx0aWYgKCBwYXJhbWV0ZXJfc3JjICYmICggcGFyYW1ldGVyX3NyYy5pc0NvbG9yIHx8XG5cdFx0XHRcdFx0cGFyYW1ldGVyX3NyYy5pc01hdHJpeDMgfHwgcGFyYW1ldGVyX3NyYy5pc01hdHJpeDQgfHxcblx0XHRcdFx0XHRwYXJhbWV0ZXJfc3JjLmlzVmVjdG9yMiB8fCBwYXJhbWV0ZXJfc3JjLmlzVmVjdG9yMyB8fCBwYXJhbWV0ZXJfc3JjLmlzVmVjdG9yNCB8fFxuXHRcdFx0XHRcdHBhcmFtZXRlcl9zcmMuaXNUZXh0dXJlICkgKSB7XG5cblx0XHRcdFx0XHR1bmlmb3Jtc19kc3RbIHUgXVsgcCBdID0gcGFyYW1ldGVyX3NyYy5jbG9uZSgpO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAoIEFycmF5LmlzQXJyYXkoIHBhcmFtZXRlcl9zcmMgKSApIHtcblxuXHRcdFx0XHRcdHVuaWZvcm1zX2RzdFsgdSBdWyBwIF0gPSBwYXJhbWV0ZXJfc3JjLnNsaWNlKCk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHVuaWZvcm1zX2RzdFsgdSBdWyBwIF0gPSBwYXJhbWV0ZXJfc3JjO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVuaWZvcm1zX2RzdDtcblxuXHR9XG5cbn07XG5cbnZhciBhbHBoYW1hcF9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9BTFBIQU1BUFxcblxcdGRpZmZ1c2VDb2xvci5hICo9IHRleHR1cmUyRCggYWxwaGFNYXAsIHZVdiApLmc7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBhbHBoYW1hcF9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0FMUEhBTUFQXFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgYWxwaGFNYXA7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBhbHBoYXRlc3RfZnJhZ21lbnQgPSBcIiNpZmRlZiBBTFBIQVRFU1RcXG5cXHRpZiAoIGRpZmZ1c2VDb2xvci5hIDwgQUxQSEFURVNUICkgZGlzY2FyZDtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGFvbWFwX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0FPTUFQXFxuXFx0ZmxvYXQgYW1iaWVudE9jY2x1c2lvbiA9ICggdGV4dHVyZTJEKCBhb01hcCwgdlV2MiApLnIgLSAxLjAgKSAqIGFvTWFwSW50ZW5zaXR5ICsgMS4wO1xcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSAqPSBhbWJpZW50T2NjbHVzaW9uO1xcblxcdCNpZiBkZWZpbmVkKCBVU0VfRU5WTUFQICkgJiYgZGVmaW5lZCggUEhZU0lDQUwgKVxcblxcdFxcdGZsb2F0IGRvdE5WID0gc2F0dXJhdGUoIGRvdCggZ2VvbWV0cnkubm9ybWFsLCBnZW9tZXRyeS52aWV3RGlyICkgKTtcXG5cXHRcXHRyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyICo9IGNvbXB1dGVTcGVjdWxhck9jY2x1c2lvbiggZG90TlYsIGFtYmllbnRPY2NsdXNpb24sIG1hdGVyaWFsLnNwZWN1bGFyUm91Z2huZXNzICk7XFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBhb21hcF9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0FPTUFQXFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgYW9NYXA7XFxuXFx0dW5pZm9ybSBmbG9hdCBhb01hcEludGVuc2l0eTtcXG4jZW5kaWZcIjtcblxudmFyIGJlZ2luX3ZlcnRleCA9IFwiXFxudmVjMyB0cmFuc2Zvcm1lZCA9IHZlYzMoIHBvc2l0aW9uICk7XFxuXCI7XG5cbnZhciBiZWdpbm5vcm1hbF92ZXJ0ZXggPSBcIlxcbnZlYzMgb2JqZWN0Tm9ybWFsID0gdmVjMyggbm9ybWFsICk7XFxuXCI7XG5cbnZhciBic2RmcyA9IFwiZmxvYXQgcHVuY3R1YWxMaWdodEludGVuc2l0eVRvSXJyYWRpYW5jZUZhY3RvciggY29uc3QgaW4gZmxvYXQgbGlnaHREaXN0YW5jZSwgY29uc3QgaW4gZmxvYXQgY3V0b2ZmRGlzdGFuY2UsIGNvbnN0IGluIGZsb2F0IGRlY2F5RXhwb25lbnQgKSB7XFxuXFx0aWYoIGRlY2F5RXhwb25lbnQgPiAwLjAgKSB7XFxuI2lmIGRlZmluZWQgKCBQSFlTSUNBTExZX0NPUlJFQ1RfTElHSFRTIClcXG5cXHRcXHRmbG9hdCBkaXN0YW5jZUZhbGxvZmYgPSAxLjAgLyBtYXgoIHBvdyggbGlnaHREaXN0YW5jZSwgZGVjYXlFeHBvbmVudCApLCAwLjAxICk7XFxuXFx0XFx0ZmxvYXQgbWF4RGlzdGFuY2VDdXRvZmZGYWN0b3IgPSBwb3cyKCBzYXR1cmF0ZSggMS4wIC0gcG93NCggbGlnaHREaXN0YW5jZSAvIGN1dG9mZkRpc3RhbmNlICkgKSApO1xcblxcdFxcdHJldHVybiBkaXN0YW5jZUZhbGxvZmYgKiBtYXhEaXN0YW5jZUN1dG9mZkZhY3RvcjtcXG4jZWxzZVxcblxcdFxcdHJldHVybiBwb3coIHNhdHVyYXRlKCAtbGlnaHREaXN0YW5jZSAvIGN1dG9mZkRpc3RhbmNlICsgMS4wICksIGRlY2F5RXhwb25lbnQgKTtcXG4jZW5kaWZcXG5cXHR9XFxuXFx0cmV0dXJuIDEuMDtcXG59XFxudmVjMyBCUkRGX0RpZmZ1c2VfTGFtYmVydCggY29uc3QgaW4gdmVjMyBkaWZmdXNlQ29sb3IgKSB7XFxuXFx0cmV0dXJuIFJFQ0lQUk9DQUxfUEkgKiBkaWZmdXNlQ29sb3I7XFxufVxcbnZlYzMgRl9TY2hsaWNrKCBjb25zdCBpbiB2ZWMzIHNwZWN1bGFyQ29sb3IsIGNvbnN0IGluIGZsb2F0IGRvdExIICkge1xcblxcdGZsb2F0IGZyZXNuZWwgPSBleHAyKCAoIC01LjU1NDczICogZG90TEggLSA2Ljk4MzE2ICkgKiBkb3RMSCApO1xcblxcdHJldHVybiAoIDEuMCAtIHNwZWN1bGFyQ29sb3IgKSAqIGZyZXNuZWwgKyBzcGVjdWxhckNvbG9yO1xcbn1cXG5mbG9hdCBHX0dHWF9TbWl0aCggY29uc3QgaW4gZmxvYXQgYWxwaGEsIGNvbnN0IGluIGZsb2F0IGRvdE5MLCBjb25zdCBpbiBmbG9hdCBkb3ROViApIHtcXG5cXHRmbG9hdCBhMiA9IHBvdzIoIGFscGhhICk7XFxuXFx0ZmxvYXQgZ2wgPSBkb3ROTCArIHNxcnQoIGEyICsgKCAxLjAgLSBhMiApICogcG93MiggZG90TkwgKSApO1xcblxcdGZsb2F0IGd2ID0gZG90TlYgKyBzcXJ0KCBhMiArICggMS4wIC0gYTIgKSAqIHBvdzIoIGRvdE5WICkgKTtcXG5cXHRyZXR1cm4gMS4wIC8gKCBnbCAqIGd2ICk7XFxufVxcbmZsb2F0IEdfR0dYX1NtaXRoQ29ycmVsYXRlZCggY29uc3QgaW4gZmxvYXQgYWxwaGEsIGNvbnN0IGluIGZsb2F0IGRvdE5MLCBjb25zdCBpbiBmbG9hdCBkb3ROViApIHtcXG5cXHRmbG9hdCBhMiA9IHBvdzIoIGFscGhhICk7XFxuXFx0ZmxvYXQgZ3YgPSBkb3ROTCAqIHNxcnQoIGEyICsgKCAxLjAgLSBhMiApICogcG93MiggZG90TlYgKSApO1xcblxcdGZsb2F0IGdsID0gZG90TlYgKiBzcXJ0KCBhMiArICggMS4wIC0gYTIgKSAqIHBvdzIoIGRvdE5MICkgKTtcXG5cXHRyZXR1cm4gMC41IC8gbWF4KCBndiArIGdsLCBFUFNJTE9OICk7XFxufVxcbmZsb2F0IERfR0dYKCBjb25zdCBpbiBmbG9hdCBhbHBoYSwgY29uc3QgaW4gZmxvYXQgZG90TkggKSB7XFxuXFx0ZmxvYXQgYTIgPSBwb3cyKCBhbHBoYSApO1xcblxcdGZsb2F0IGRlbm9tID0gcG93MiggZG90TkggKSAqICggYTIgLSAxLjAgKSArIDEuMDtcXG5cXHRyZXR1cm4gUkVDSVBST0NBTF9QSSAqIGEyIC8gcG93MiggZGVub20gKTtcXG59XFxudmVjMyBCUkRGX1NwZWN1bGFyX0dHWCggY29uc3QgaW4gSW5jaWRlbnRMaWdodCBpbmNpZGVudExpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiB2ZWMzIHNwZWN1bGFyQ29sb3IsIGNvbnN0IGluIGZsb2F0IHJvdWdobmVzcyApIHtcXG5cXHRmbG9hdCBhbHBoYSA9IHBvdzIoIHJvdWdobmVzcyApO1xcblxcdHZlYzMgaGFsZkRpciA9IG5vcm1hbGl6ZSggaW5jaWRlbnRMaWdodC5kaXJlY3Rpb24gKyBnZW9tZXRyeS52aWV3RGlyICk7XFxuXFx0ZmxvYXQgZG90TkwgPSBzYXR1cmF0ZSggZG90KCBnZW9tZXRyeS5ub3JtYWwsIGluY2lkZW50TGlnaHQuZGlyZWN0aW9uICkgKTtcXG5cXHRmbG9hdCBkb3ROViA9IHNhdHVyYXRlKCBkb3QoIGdlb21ldHJ5Lm5vcm1hbCwgZ2VvbWV0cnkudmlld0RpciApICk7XFxuXFx0ZmxvYXQgZG90TkggPSBzYXR1cmF0ZSggZG90KCBnZW9tZXRyeS5ub3JtYWwsIGhhbGZEaXIgKSApO1xcblxcdGZsb2F0IGRvdExIID0gc2F0dXJhdGUoIGRvdCggaW5jaWRlbnRMaWdodC5kaXJlY3Rpb24sIGhhbGZEaXIgKSApO1xcblxcdHZlYzMgRiA9IEZfU2NobGljayggc3BlY3VsYXJDb2xvciwgZG90TEggKTtcXG5cXHRmbG9hdCBHID0gR19HR1hfU21pdGhDb3JyZWxhdGVkKCBhbHBoYSwgZG90TkwsIGRvdE5WICk7XFxuXFx0ZmxvYXQgRCA9IERfR0dYKCBhbHBoYSwgZG90TkggKTtcXG5cXHRyZXR1cm4gRiAqICggRyAqIEQgKTtcXG59XFxudmVjMiBMVENfVXYoIGNvbnN0IGluIHZlYzMgTiwgY29uc3QgaW4gdmVjMyBWLCBjb25zdCBpbiBmbG9hdCByb3VnaG5lc3MgKSB7XFxuXFx0Y29uc3QgZmxvYXQgTFVUX1NJWkUgID0gNjQuMDtcXG5cXHRjb25zdCBmbG9hdCBMVVRfU0NBTEUgPSAoIExVVF9TSVpFIC0gMS4wICkgLyBMVVRfU0laRTtcXG5cXHRjb25zdCBmbG9hdCBMVVRfQklBUyAgPSAwLjUgLyBMVVRfU0laRTtcXG5cXHRmbG9hdCB0aGV0YSA9IGFjb3MoIGRvdCggTiwgViApICk7XFxuXFx0dmVjMiB1diA9IHZlYzIoXFxuXFx0XFx0c3FydCggc2F0dXJhdGUoIHJvdWdobmVzcyApICksXFxuXFx0XFx0c2F0dXJhdGUoIHRoZXRhIC8gKCAwLjUgKiBQSSApICkgKTtcXG5cXHR1diA9IHV2ICogTFVUX1NDQUxFICsgTFVUX0JJQVM7XFxuXFx0cmV0dXJuIHV2O1xcbn1cXG5mbG9hdCBMVENfQ2xpcHBlZFNwaGVyZUZvcm1GYWN0b3IoIGNvbnN0IGluIHZlYzMgZiApIHtcXG5cXHRmbG9hdCBsID0gbGVuZ3RoKCBmICk7XFxuXFx0cmV0dXJuIG1heCggKCBsICogbCArIGYueiApIC8gKCBsICsgMS4wICksIDAuMCApO1xcbn1cXG52ZWMzIExUQ19FZGdlVmVjdG9yRm9ybUZhY3RvciggY29uc3QgaW4gdmVjMyB2MSwgY29uc3QgaW4gdmVjMyB2MiApIHtcXG5cXHRmbG9hdCB4ID0gZG90KCB2MSwgdjIgKTtcXG5cXHRmbG9hdCB5ID0gYWJzKCB4ICk7XFxuXFx0ZmxvYXQgYSA9IDAuODYyNjcgKyAoMC40OTc4OCArIDAuMDE0MzYgKiB5ICkgKiB5O1xcblxcdGZsb2F0IGIgPSAzLjQ1MDY4ICsgKDQuMTg4MTQgKyB5KSAqIHk7XFxuXFx0ZmxvYXQgdiA9IGEgLyBiO1xcblxcdGZsb2F0IHRoZXRhX3NpbnRoZXRhID0gKHggPiAwLjApID8gdiA6IDAuNSAqIGludmVyc2VzcXJ0KCAxLjAgLSB4ICogeCApIC0gdjtcXG5cXHRyZXR1cm4gY3Jvc3MoIHYxLCB2MiApICogdGhldGFfc2ludGhldGE7XFxufVxcbnZlYzMgTFRDX0V2YWx1YXRlKCBjb25zdCBpbiB2ZWMzIE4sIGNvbnN0IGluIHZlYzMgViwgY29uc3QgaW4gdmVjMyBQLCBjb25zdCBpbiBtYXQzIG1JbnYsIGNvbnN0IGluIHZlYzMgcmVjdENvb3Jkc1sgNCBdICkge1xcblxcdHZlYzMgdjEgPSByZWN0Q29vcmRzWyAxIF0gLSByZWN0Q29vcmRzWyAwIF07XFxuXFx0dmVjMyB2MiA9IHJlY3RDb29yZHNbIDMgXSAtIHJlY3RDb29yZHNbIDAgXTtcXG5cXHR2ZWMzIGxpZ2h0Tm9ybWFsID0gY3Jvc3MoIHYxLCB2MiApO1xcblxcdGlmKCBkb3QoIGxpZ2h0Tm9ybWFsLCBQIC0gcmVjdENvb3Jkc1sgMCBdICkgPCAwLjAgKSByZXR1cm4gdmVjMyggMC4wICk7XFxuXFx0dmVjMyBUMSwgVDI7XFxuXFx0VDEgPSBub3JtYWxpemUoIFYgLSBOICogZG90KCBWLCBOICkgKTtcXG5cXHRUMiA9IC0gY3Jvc3MoIE4sIFQxICk7XFxuXFx0bWF0MyBtYXQgPSBtSW52ICogdHJhbnNwb3NlKCBtYXQzKCBUMSwgVDIsIE4gKSApO1xcblxcdHZlYzMgY29vcmRzWyA0IF07XFxuXFx0Y29vcmRzWyAwIF0gPSBtYXQgKiAoIHJlY3RDb29yZHNbIDAgXSAtIFAgKTtcXG5cXHRjb29yZHNbIDEgXSA9IG1hdCAqICggcmVjdENvb3Jkc1sgMSBdIC0gUCApO1xcblxcdGNvb3Jkc1sgMiBdID0gbWF0ICogKCByZWN0Q29vcmRzWyAyIF0gLSBQICk7XFxuXFx0Y29vcmRzWyAzIF0gPSBtYXQgKiAoIHJlY3RDb29yZHNbIDMgXSAtIFAgKTtcXG5cXHRjb29yZHNbIDAgXSA9IG5vcm1hbGl6ZSggY29vcmRzWyAwIF0gKTtcXG5cXHRjb29yZHNbIDEgXSA9IG5vcm1hbGl6ZSggY29vcmRzWyAxIF0gKTtcXG5cXHRjb29yZHNbIDIgXSA9IG5vcm1hbGl6ZSggY29vcmRzWyAyIF0gKTtcXG5cXHRjb29yZHNbIDMgXSA9IG5vcm1hbGl6ZSggY29vcmRzWyAzIF0gKTtcXG5cXHR2ZWMzIHZlY3RvckZvcm1GYWN0b3IgPSB2ZWMzKCAwLjAgKTtcXG5cXHR2ZWN0b3JGb3JtRmFjdG9yICs9IExUQ19FZGdlVmVjdG9yRm9ybUZhY3RvciggY29vcmRzWyAwIF0sIGNvb3Jkc1sgMSBdICk7XFxuXFx0dmVjdG9yRm9ybUZhY3RvciArPSBMVENfRWRnZVZlY3RvckZvcm1GYWN0b3IoIGNvb3Jkc1sgMSBdLCBjb29yZHNbIDIgXSApO1xcblxcdHZlY3RvckZvcm1GYWN0b3IgKz0gTFRDX0VkZ2VWZWN0b3JGb3JtRmFjdG9yKCBjb29yZHNbIDIgXSwgY29vcmRzWyAzIF0gKTtcXG5cXHR2ZWN0b3JGb3JtRmFjdG9yICs9IExUQ19FZGdlVmVjdG9yRm9ybUZhY3RvciggY29vcmRzWyAzIF0sIGNvb3Jkc1sgMCBdICk7XFxuXFx0dmVjMyByZXN1bHQgPSB2ZWMzKCBMVENfQ2xpcHBlZFNwaGVyZUZvcm1GYWN0b3IoIHZlY3RvckZvcm1GYWN0b3IgKSApO1xcblxcdHJldHVybiByZXN1bHQ7XFxufVxcbnZlYzMgQlJERl9TcGVjdWxhcl9HR1hfRW52aXJvbm1lbnQoIGNvbnN0IGluIEdlb21ldHJpY0NvbnRleHQgZ2VvbWV0cnksIGNvbnN0IGluIHZlYzMgc3BlY3VsYXJDb2xvciwgY29uc3QgaW4gZmxvYXQgcm91Z2huZXNzICkge1xcblxcdGZsb2F0IGRvdE5WID0gc2F0dXJhdGUoIGRvdCggZ2VvbWV0cnkubm9ybWFsLCBnZW9tZXRyeS52aWV3RGlyICkgKTtcXG5cXHRjb25zdCB2ZWM0IGMwID0gdmVjNCggLSAxLCAtIDAuMDI3NSwgLSAwLjU3MiwgMC4wMjIgKTtcXG5cXHRjb25zdCB2ZWM0IGMxID0gdmVjNCggMSwgMC4wNDI1LCAxLjA0LCAtIDAuMDQgKTtcXG5cXHR2ZWM0IHIgPSByb3VnaG5lc3MgKiBjMCArIGMxO1xcblxcdGZsb2F0IGEwMDQgPSBtaW4oIHIueCAqIHIueCwgZXhwMiggLSA5LjI4ICogZG90TlYgKSApICogci54ICsgci55O1xcblxcdHZlYzIgQUIgPSB2ZWMyKCAtMS4wNCwgMS4wNCApICogYTAwNCArIHIuenc7XFxuXFx0cmV0dXJuIHNwZWN1bGFyQ29sb3IgKiBBQi54ICsgQUIueTtcXG59XFxuZmxvYXQgR19CbGlublBob25nX0ltcGxpY2l0KCApIHtcXG5cXHRyZXR1cm4gMC4yNTtcXG59XFxuZmxvYXQgRF9CbGlublBob25nKCBjb25zdCBpbiBmbG9hdCBzaGluaW5lc3MsIGNvbnN0IGluIGZsb2F0IGRvdE5IICkge1xcblxcdHJldHVybiBSRUNJUFJPQ0FMX1BJICogKCBzaGluaW5lc3MgKiAwLjUgKyAxLjAgKSAqIHBvdyggZG90TkgsIHNoaW5pbmVzcyApO1xcbn1cXG52ZWMzIEJSREZfU3BlY3VsYXJfQmxpbm5QaG9uZyggY29uc3QgaW4gSW5jaWRlbnRMaWdodCBpbmNpZGVudExpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiB2ZWMzIHNwZWN1bGFyQ29sb3IsIGNvbnN0IGluIGZsb2F0IHNoaW5pbmVzcyApIHtcXG5cXHR2ZWMzIGhhbGZEaXIgPSBub3JtYWxpemUoIGluY2lkZW50TGlnaHQuZGlyZWN0aW9uICsgZ2VvbWV0cnkudmlld0RpciApO1xcblxcdGZsb2F0IGRvdE5IID0gc2F0dXJhdGUoIGRvdCggZ2VvbWV0cnkubm9ybWFsLCBoYWxmRGlyICkgKTtcXG5cXHRmbG9hdCBkb3RMSCA9IHNhdHVyYXRlKCBkb3QoIGluY2lkZW50TGlnaHQuZGlyZWN0aW9uLCBoYWxmRGlyICkgKTtcXG5cXHR2ZWMzIEYgPSBGX1NjaGxpY2soIHNwZWN1bGFyQ29sb3IsIGRvdExIICk7XFxuXFx0ZmxvYXQgRyA9IEdfQmxpbm5QaG9uZ19JbXBsaWNpdCggKTtcXG5cXHRmbG9hdCBEID0gRF9CbGlublBob25nKCBzaGluaW5lc3MsIGRvdE5IICk7XFxuXFx0cmV0dXJuIEYgKiAoIEcgKiBEICk7XFxufVxcbmZsb2F0IEdHWFJvdWdobmVzc1RvQmxpbm5FeHBvbmVudCggY29uc3QgaW4gZmxvYXQgZ2d4Um91Z2huZXNzICkge1xcblxcdHJldHVybiAoIDIuMCAvIHBvdzIoIGdneFJvdWdobmVzcyArIDAuMDAwMSApIC0gMi4wICk7XFxufVxcbmZsb2F0IEJsaW5uRXhwb25lbnRUb0dHWFJvdWdobmVzcyggY29uc3QgaW4gZmxvYXQgYmxpbm5FeHBvbmVudCApIHtcXG5cXHRyZXR1cm4gc3FydCggMi4wIC8gKCBibGlubkV4cG9uZW50ICsgMi4wICkgKTtcXG59XFxuXCI7XG5cbnZhciBidW1wbWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfQlVNUE1BUFxcblxcdHVuaWZvcm0gc2FtcGxlcjJEIGJ1bXBNYXA7XFxuXFx0dW5pZm9ybSBmbG9hdCBidW1wU2NhbGU7XFxuXFx0dmVjMiBkSGR4eV9md2QoKSB7XFxuXFx0XFx0dmVjMiBkU1RkeCA9IGRGZHgoIHZVdiApO1xcblxcdFxcdHZlYzIgZFNUZHkgPSBkRmR5KCB2VXYgKTtcXG5cXHRcXHRmbG9hdCBIbGwgPSBidW1wU2NhbGUgKiB0ZXh0dXJlMkQoIGJ1bXBNYXAsIHZVdiApLng7XFxuXFx0XFx0ZmxvYXQgZEJ4ID0gYnVtcFNjYWxlICogdGV4dHVyZTJEKCBidW1wTWFwLCB2VXYgKyBkU1RkeCApLnggLSBIbGw7XFxuXFx0XFx0ZmxvYXQgZEJ5ID0gYnVtcFNjYWxlICogdGV4dHVyZTJEKCBidW1wTWFwLCB2VXYgKyBkU1RkeSApLnggLSBIbGw7XFxuXFx0XFx0cmV0dXJuIHZlYzIoIGRCeCwgZEJ5ICk7XFxuXFx0fVxcblxcdHZlYzMgcGVydHVyYk5vcm1hbEFyYiggdmVjMyBzdXJmX3BvcywgdmVjMyBzdXJmX25vcm0sIHZlYzIgZEhkeHkgKSB7XFxuXFx0XFx0dmVjMyB2U2lnbWFYID0gZEZkeCggc3VyZl9wb3MgKTtcXG5cXHRcXHR2ZWMzIHZTaWdtYVkgPSBkRmR5KCBzdXJmX3BvcyApO1xcblxcdFxcdHZlYzMgdk4gPSBzdXJmX25vcm07XFxuXFx0XFx0dmVjMyBSMSA9IGNyb3NzKCB2U2lnbWFZLCB2TiApO1xcblxcdFxcdHZlYzMgUjIgPSBjcm9zcyggdk4sIHZTaWdtYVggKTtcXG5cXHRcXHRmbG9hdCBmRGV0ID0gZG90KCB2U2lnbWFYLCBSMSApO1xcblxcdFxcdHZlYzMgdkdyYWQgPSBzaWduKCBmRGV0ICkgKiAoIGRIZHh5LnggKiBSMSArIGRIZHh5LnkgKiBSMiApO1xcblxcdFxcdHJldHVybiBub3JtYWxpemUoIGFicyggZkRldCApICogc3VyZl9ub3JtIC0gdkdyYWQgKTtcXG5cXHR9XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQgPSBcIiNpZiBOVU1fQ0xJUFBJTkdfUExBTkVTID4gMFxcblxcdGZvciAoIGludCBpID0gMDsgaSA8IFVOSU9OX0NMSVBQSU5HX1BMQU5FUzsgKysgaSApIHtcXG5cXHRcXHR2ZWM0IHBsYW5lID0gY2xpcHBpbmdQbGFuZXNbIGkgXTtcXG5cXHRcXHRpZiAoIGRvdCggdlZpZXdQb3NpdGlvbiwgcGxhbmUueHl6ICkgPiBwbGFuZS53ICkgZGlzY2FyZDtcXG5cXHR9XFxuXFx0XFx0XFxuXFx0I2lmIFVOSU9OX0NMSVBQSU5HX1BMQU5FUyA8IE5VTV9DTElQUElOR19QTEFORVNcXG5cXHRcXHRib29sIGNsaXBwZWQgPSB0cnVlO1xcblxcdFxcdGZvciAoIGludCBpID0gVU5JT05fQ0xJUFBJTkdfUExBTkVTOyBpIDwgTlVNX0NMSVBQSU5HX1BMQU5FUzsgKysgaSApIHtcXG5cXHRcXHRcXHR2ZWM0IHBsYW5lID0gY2xpcHBpbmdQbGFuZXNbIGkgXTtcXG5cXHRcXHRcXHRjbGlwcGVkID0gKCBkb3QoIHZWaWV3UG9zaXRpb24sIHBsYW5lLnh5eiApID4gcGxhbmUudyApICYmIGNsaXBwZWQ7XFxuXFx0XFx0fVxcblxcdFxcdGlmICggY2xpcHBlZCApIGRpc2NhcmQ7XFxuXFx0XFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBjbGlwcGluZ19wbGFuZXNfcGFyc19mcmFnbWVudCA9IFwiI2lmIE5VTV9DTElQUElOR19QTEFORVMgPiAwXFxuXFx0I2lmICEgZGVmaW5lZCggUEhZU0lDQUwgKSAmJiAhIGRlZmluZWQoIFBIT05HIClcXG5cXHRcXHR2YXJ5aW5nIHZlYzMgdlZpZXdQb3NpdGlvbjtcXG5cXHQjZW5kaWZcXG5cXHR1bmlmb3JtIHZlYzQgY2xpcHBpbmdQbGFuZXNbIE5VTV9DTElQUElOR19QTEFORVMgXTtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleCA9IFwiI2lmIE5VTV9DTElQUElOR19QTEFORVMgPiAwICYmICEgZGVmaW5lZCggUEhZU0lDQUwgKSAmJiAhIGRlZmluZWQoIFBIT05HIClcXG5cXHR2YXJ5aW5nIHZlYzMgdlZpZXdQb3NpdGlvbjtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXggPSBcIiNpZiBOVU1fQ0xJUFBJTkdfUExBTkVTID4gMCAmJiAhIGRlZmluZWQoIFBIWVNJQ0FMICkgJiYgISBkZWZpbmVkKCBQSE9ORyApXFxuXFx0dlZpZXdQb3NpdGlvbiA9IC0gbXZQb3NpdGlvbi54eXo7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBjb2xvcl9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9DT0xPUlxcblxcdGRpZmZ1c2VDb2xvci5yZ2IgKj0gdkNvbG9yO1xcbiNlbmRpZlwiO1xuXG52YXIgY29sb3JfcGFyc19mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9DT0xPUlxcblxcdHZhcnlpbmcgdmVjMyB2Q29sb3I7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBjb2xvcl9wYXJzX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9DT0xPUlxcblxcdHZhcnlpbmcgdmVjMyB2Q29sb3I7XFxuI2VuZGlmXCI7XG5cbnZhciBjb2xvcl92ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfQ09MT1JcXG5cXHR2Q29sb3IueHl6ID0gY29sb3IueHl6O1xcbiNlbmRpZlwiO1xuXG52YXIgY29tbW9uID0gXCIjZGVmaW5lIFBJIDMuMTQxNTkyNjUzNTlcXG4jZGVmaW5lIFBJMiA2LjI4MzE4NTMwNzE4XFxuI2RlZmluZSBQSV9IQUxGIDEuNTcwNzk2MzI2Nzk0OVxcbiNkZWZpbmUgUkVDSVBST0NBTF9QSSAwLjMxODMwOTg4NjE4XFxuI2RlZmluZSBSRUNJUFJPQ0FMX1BJMiAwLjE1OTE1NDk0XFxuI2RlZmluZSBMT0cyIDEuNDQyNjk1XFxuI2RlZmluZSBFUFNJTE9OIDFlLTZcXG4jZGVmaW5lIHNhdHVyYXRlKGEpIGNsYW1wKCBhLCAwLjAsIDEuMCApXFxuI2RlZmluZSB3aGl0ZUNvbXBsaW1lbnQoYSkgKCAxLjAgLSBzYXR1cmF0ZSggYSApIClcXG5mbG9hdCBwb3cyKCBjb25zdCBpbiBmbG9hdCB4ICkgeyByZXR1cm4geCp4OyB9XFxuZmxvYXQgcG93MyggY29uc3QgaW4gZmxvYXQgeCApIHsgcmV0dXJuIHgqeCp4OyB9XFxuZmxvYXQgcG93NCggY29uc3QgaW4gZmxvYXQgeCApIHsgZmxvYXQgeDIgPSB4Kng7IHJldHVybiB4Mip4MjsgfVxcbmZsb2F0IGF2ZXJhZ2UoIGNvbnN0IGluIHZlYzMgY29sb3IgKSB7IHJldHVybiBkb3QoIGNvbG9yLCB2ZWMzKCAwLjMzMzMgKSApOyB9XFxuaGlnaHAgZmxvYXQgcmFuZCggY29uc3QgaW4gdmVjMiB1diApIHtcXG5cXHRjb25zdCBoaWdocCBmbG9hdCBhID0gMTIuOTg5OCwgYiA9IDc4LjIzMywgYyA9IDQzNzU4LjU0NTM7XFxuXFx0aGlnaHAgZmxvYXQgZHQgPSBkb3QoIHV2Lnh5LCB2ZWMyKCBhLGIgKSApLCBzbiA9IG1vZCggZHQsIFBJICk7XFxuXFx0cmV0dXJuIGZyYWN0KHNpbihzbikgKiBjKTtcXG59XFxuc3RydWN0IEluY2lkZW50TGlnaHQge1xcblxcdHZlYzMgY29sb3I7XFxuXFx0dmVjMyBkaXJlY3Rpb247XFxuXFx0Ym9vbCB2aXNpYmxlO1xcbn07XFxuc3RydWN0IFJlZmxlY3RlZExpZ2h0IHtcXG5cXHR2ZWMzIGRpcmVjdERpZmZ1c2U7XFxuXFx0dmVjMyBkaXJlY3RTcGVjdWxhcjtcXG5cXHR2ZWMzIGluZGlyZWN0RGlmZnVzZTtcXG5cXHR2ZWMzIGluZGlyZWN0U3BlY3VsYXI7XFxufTtcXG5zdHJ1Y3QgR2VvbWV0cmljQ29udGV4dCB7XFxuXFx0dmVjMyBwb3NpdGlvbjtcXG5cXHR2ZWMzIG5vcm1hbDtcXG5cXHR2ZWMzIHZpZXdEaXI7XFxufTtcXG52ZWMzIHRyYW5zZm9ybURpcmVjdGlvbiggaW4gdmVjMyBkaXIsIGluIG1hdDQgbWF0cml4ICkge1xcblxcdHJldHVybiBub3JtYWxpemUoICggbWF0cml4ICogdmVjNCggZGlyLCAwLjAgKSApLnh5eiApO1xcbn1cXG52ZWMzIGludmVyc2VUcmFuc2Zvcm1EaXJlY3Rpb24oIGluIHZlYzMgZGlyLCBpbiBtYXQ0IG1hdHJpeCApIHtcXG5cXHRyZXR1cm4gbm9ybWFsaXplKCAoIHZlYzQoIGRpciwgMC4wICkgKiBtYXRyaXggKS54eXogKTtcXG59XFxudmVjMyBwcm9qZWN0T25QbGFuZShpbiB2ZWMzIHBvaW50LCBpbiB2ZWMzIHBvaW50T25QbGFuZSwgaW4gdmVjMyBwbGFuZU5vcm1hbCApIHtcXG5cXHRmbG9hdCBkaXN0YW5jZSA9IGRvdCggcGxhbmVOb3JtYWwsIHBvaW50IC0gcG9pbnRPblBsYW5lICk7XFxuXFx0cmV0dXJuIC0gZGlzdGFuY2UgKiBwbGFuZU5vcm1hbCArIHBvaW50O1xcbn1cXG5mbG9hdCBzaWRlT2ZQbGFuZSggaW4gdmVjMyBwb2ludCwgaW4gdmVjMyBwb2ludE9uUGxhbmUsIGluIHZlYzMgcGxhbmVOb3JtYWwgKSB7XFxuXFx0cmV0dXJuIHNpZ24oIGRvdCggcG9pbnQgLSBwb2ludE9uUGxhbmUsIHBsYW5lTm9ybWFsICkgKTtcXG59XFxudmVjMyBsaW5lUGxhbmVJbnRlcnNlY3QoIGluIHZlYzMgcG9pbnRPbkxpbmUsIGluIHZlYzMgbGluZURpcmVjdGlvbiwgaW4gdmVjMyBwb2ludE9uUGxhbmUsIGluIHZlYzMgcGxhbmVOb3JtYWwgKSB7XFxuXFx0cmV0dXJuIGxpbmVEaXJlY3Rpb24gKiAoIGRvdCggcGxhbmVOb3JtYWwsIHBvaW50T25QbGFuZSAtIHBvaW50T25MaW5lICkgLyBkb3QoIHBsYW5lTm9ybWFsLCBsaW5lRGlyZWN0aW9uICkgKSArIHBvaW50T25MaW5lO1xcbn1cXG5tYXQzIHRyYW5zcG9zZSggY29uc3QgaW4gbWF0MyB2ICkge1xcblxcdG1hdDMgdG1wO1xcblxcdHRtcFswXSA9IHZlYzModlswXS54LCB2WzFdLngsIHZbMl0ueCk7XFxuXFx0dG1wWzFdID0gdmVjMyh2WzBdLnksIHZbMV0ueSwgdlsyXS55KTtcXG5cXHR0bXBbMl0gPSB2ZWMzKHZbMF0ueiwgdlsxXS56LCB2WzJdLnopO1xcblxcdHJldHVybiB0bXA7XFxufVxcblwiO1xuXG52YXIgY3ViZV91dl9yZWZsZWN0aW9uX2ZyYWdtZW50ID0gXCIjaWZkZWYgRU5WTUFQX1RZUEVfQ1VCRV9VVlxcbiNkZWZpbmUgY3ViZVVWX3RleHR1cmVTaXplICgxMDI0LjApXFxuaW50IGdldEZhY2VGcm9tRGlyZWN0aW9uKHZlYzMgZGlyZWN0aW9uKSB7XFxuXFx0dmVjMyBhYnNEaXJlY3Rpb24gPSBhYnMoZGlyZWN0aW9uKTtcXG5cXHRpbnQgZmFjZSA9IC0xO1xcblxcdGlmKCBhYnNEaXJlY3Rpb24ueCA+IGFic0RpcmVjdGlvbi56ICkge1xcblxcdFxcdGlmKGFic0RpcmVjdGlvbi54ID4gYWJzRGlyZWN0aW9uLnkgKVxcblxcdFxcdFxcdGZhY2UgPSBkaXJlY3Rpb24ueCA+IDAuMCA/IDAgOiAzO1xcblxcdFxcdGVsc2VcXG5cXHRcXHRcXHRmYWNlID0gZGlyZWN0aW9uLnkgPiAwLjAgPyAxIDogNDtcXG5cXHR9XFxuXFx0ZWxzZSB7XFxuXFx0XFx0aWYoYWJzRGlyZWN0aW9uLnogPiBhYnNEaXJlY3Rpb24ueSApXFxuXFx0XFx0XFx0ZmFjZSA9IGRpcmVjdGlvbi56ID4gMC4wID8gMiA6IDU7XFxuXFx0XFx0ZWxzZVxcblxcdFxcdFxcdGZhY2UgPSBkaXJlY3Rpb24ueSA+IDAuMCA/IDEgOiA0O1xcblxcdH1cXG5cXHRyZXR1cm4gZmFjZTtcXG59XFxuI2RlZmluZSBjdWJlVVZfbWF4TG9kczEgIChsb2cyKGN1YmVVVl90ZXh0dXJlU2l6ZSowLjI1KSAtIDEuMClcXG4jZGVmaW5lIGN1YmVVVl9yYW5nZUNsYW1wIChleHAyKCg2LjAgLSAxLjApICogMi4wKSlcXG52ZWMyIE1pcExldmVsSW5mbyggdmVjMyB2ZWMsIGZsb2F0IHJvdWdobmVzc0xldmVsLCBmbG9hdCByb3VnaG5lc3MgKSB7XFxuXFx0ZmxvYXQgc2NhbGUgPSBleHAyKGN1YmVVVl9tYXhMb2RzMSAtIHJvdWdobmVzc0xldmVsKTtcXG5cXHRmbG9hdCBkeFJvdWdobmVzcyA9IGRGZHgocm91Z2huZXNzKTtcXG5cXHRmbG9hdCBkeVJvdWdobmVzcyA9IGRGZHkocm91Z2huZXNzKTtcXG5cXHR2ZWMzIGR4ID0gZEZkeCggdmVjICogc2NhbGUgKiBkeFJvdWdobmVzcyApO1xcblxcdHZlYzMgZHkgPSBkRmR5KCB2ZWMgKiBzY2FsZSAqIGR5Um91Z2huZXNzICk7XFxuXFx0ZmxvYXQgZCA9IG1heCggZG90KCBkeCwgZHggKSwgZG90KCBkeSwgZHkgKSApO1xcblxcdGQgPSBjbGFtcChkLCAxLjAsIGN1YmVVVl9yYW5nZUNsYW1wKTtcXG5cXHRmbG9hdCBtaXBMZXZlbCA9IDAuNSAqIGxvZzIoZCk7XFxuXFx0cmV0dXJuIHZlYzIoZmxvb3IobWlwTGV2ZWwpLCBmcmFjdChtaXBMZXZlbCkpO1xcbn1cXG4jZGVmaW5lIGN1YmVVVl9tYXhMb2RzMiAobG9nMihjdWJlVVZfdGV4dHVyZVNpemUqMC4yNSkgLSAyLjApXFxuI2RlZmluZSBjdWJlVVZfcmNwVGV4dHVyZVNpemUgKDEuMCAvIGN1YmVVVl90ZXh0dXJlU2l6ZSlcXG52ZWMyIGdldEN1YmVVVih2ZWMzIGRpcmVjdGlvbiwgZmxvYXQgcm91Z2huZXNzTGV2ZWwsIGZsb2F0IG1pcExldmVsKSB7XFxuXFx0bWlwTGV2ZWwgPSByb3VnaG5lc3NMZXZlbCA+IGN1YmVVVl9tYXhMb2RzMiAtIDMuMCA/IDAuMCA6IG1pcExldmVsO1xcblxcdGZsb2F0IGEgPSAxNi4wICogY3ViZVVWX3JjcFRleHR1cmVTaXplO1xcblxcdHZlYzIgZXhwMl9wYWNrZWQgPSBleHAyKCB2ZWMyKCByb3VnaG5lc3NMZXZlbCwgbWlwTGV2ZWwgKSApO1xcblxcdHZlYzIgcmNwX2V4cDJfcGFja2VkID0gdmVjMiggMS4wICkgLyBleHAyX3BhY2tlZDtcXG5cXHRmbG9hdCBwb3dTY2FsZSA9IGV4cDJfcGFja2VkLnggKiBleHAyX3BhY2tlZC55O1xcblxcdGZsb2F0IHNjYWxlID0gcmNwX2V4cDJfcGFja2VkLnggKiByY3BfZXhwMl9wYWNrZWQueSAqIDAuMjU7XFxuXFx0ZmxvYXQgbWlwT2Zmc2V0ID0gMC43NSooMS4wIC0gcmNwX2V4cDJfcGFja2VkLnkpICogcmNwX2V4cDJfcGFja2VkLng7XFxuXFx0Ym9vbCBiUmVzID0gbWlwTGV2ZWwgPT0gMC4wO1xcblxcdHNjYWxlID0gIGJSZXMgJiYgKHNjYWxlIDwgYSkgPyBhIDogc2NhbGU7XFxuXFx0dmVjMyByO1xcblxcdHZlYzIgb2Zmc2V0O1xcblxcdGludCBmYWNlID0gZ2V0RmFjZUZyb21EaXJlY3Rpb24oZGlyZWN0aW9uKTtcXG5cXHRmbG9hdCByY3BQb3dTY2FsZSA9IDEuMCAvIHBvd1NjYWxlO1xcblxcdGlmKCBmYWNlID09IDApIHtcXG5cXHRcXHRyID0gdmVjMyhkaXJlY3Rpb24ueCwgLWRpcmVjdGlvbi56LCBkaXJlY3Rpb24ueSk7XFxuXFx0XFx0b2Zmc2V0ID0gdmVjMigwLjArbWlwT2Zmc2V0LDAuNzUgKiByY3BQb3dTY2FsZSk7XFxuXFx0XFx0b2Zmc2V0LnkgPSBiUmVzICYmIChvZmZzZXQueSA8IDIuMCphKSA/IGEgOiBvZmZzZXQueTtcXG5cXHR9XFxuXFx0ZWxzZSBpZiggZmFjZSA9PSAxKSB7XFxuXFx0XFx0ciA9IHZlYzMoZGlyZWN0aW9uLnksIGRpcmVjdGlvbi54LCBkaXJlY3Rpb24ueik7XFxuXFx0XFx0b2Zmc2V0ID0gdmVjMihzY2FsZSttaXBPZmZzZXQsIDAuNzUgKiByY3BQb3dTY2FsZSk7XFxuXFx0XFx0b2Zmc2V0LnkgPSBiUmVzICYmIChvZmZzZXQueSA8IDIuMCphKSA/IGEgOiBvZmZzZXQueTtcXG5cXHR9XFxuXFx0ZWxzZSBpZiggZmFjZSA9PSAyKSB7XFxuXFx0XFx0ciA9IHZlYzMoZGlyZWN0aW9uLnosIGRpcmVjdGlvbi54LCBkaXJlY3Rpb24ueSk7XFxuXFx0XFx0b2Zmc2V0ID0gdmVjMigyLjAqc2NhbGUrbWlwT2Zmc2V0LCAwLjc1ICogcmNwUG93U2NhbGUpO1xcblxcdFxcdG9mZnNldC55ID0gYlJlcyAmJiAob2Zmc2V0LnkgPCAyLjAqYSkgPyBhIDogb2Zmc2V0Lnk7XFxuXFx0fVxcblxcdGVsc2UgaWYoIGZhY2UgPT0gMykge1xcblxcdFxcdHIgPSB2ZWMzKGRpcmVjdGlvbi54LCBkaXJlY3Rpb24ueiwgZGlyZWN0aW9uLnkpO1xcblxcdFxcdG9mZnNldCA9IHZlYzIoMC4wK21pcE9mZnNldCwwLjUgKiByY3BQb3dTY2FsZSk7XFxuXFx0XFx0b2Zmc2V0LnkgPSBiUmVzICYmIChvZmZzZXQueSA8IDIuMCphKSA/IDAuMCA6IG9mZnNldC55O1xcblxcdH1cXG5cXHRlbHNlIGlmKCBmYWNlID09IDQpIHtcXG5cXHRcXHRyID0gdmVjMyhkaXJlY3Rpb24ueSwgZGlyZWN0aW9uLngsIC1kaXJlY3Rpb24ueik7XFxuXFx0XFx0b2Zmc2V0ID0gdmVjMihzY2FsZSttaXBPZmZzZXQsIDAuNSAqIHJjcFBvd1NjYWxlKTtcXG5cXHRcXHRvZmZzZXQueSA9IGJSZXMgJiYgKG9mZnNldC55IDwgMi4wKmEpID8gMC4wIDogb2Zmc2V0Lnk7XFxuXFx0fVxcblxcdGVsc2Uge1xcblxcdFxcdHIgPSB2ZWMzKGRpcmVjdGlvbi56LCAtZGlyZWN0aW9uLngsIGRpcmVjdGlvbi55KTtcXG5cXHRcXHRvZmZzZXQgPSB2ZWMyKDIuMCpzY2FsZSttaXBPZmZzZXQsIDAuNSAqIHJjcFBvd1NjYWxlKTtcXG5cXHRcXHRvZmZzZXQueSA9IGJSZXMgJiYgKG9mZnNldC55IDwgMi4wKmEpID8gMC4wIDogb2Zmc2V0Lnk7XFxuXFx0fVxcblxcdHIgPSBub3JtYWxpemUocik7XFxuXFx0ZmxvYXQgdGV4ZWxPZmZzZXQgPSAwLjUgKiBjdWJlVVZfcmNwVGV4dHVyZVNpemU7XFxuXFx0dmVjMiBzID0gKCByLnl6IC8gYWJzKCByLnggKSArIHZlYzIoIDEuMCApICkgKiAwLjU7XFxuXFx0dmVjMiBiYXNlID0gb2Zmc2V0ICsgdmVjMiggdGV4ZWxPZmZzZXQgKTtcXG5cXHRyZXR1cm4gYmFzZSArIHMgKiAoIHNjYWxlIC0gMi4wICogdGV4ZWxPZmZzZXQgKTtcXG59XFxuI2RlZmluZSBjdWJlVVZfbWF4TG9kczMgKGxvZzIoY3ViZVVWX3RleHR1cmVTaXplKjAuMjUpIC0gMy4wKVxcbnZlYzQgdGV4dHVyZUN1YmVVVih2ZWMzIHJlZmxlY3RlZERpcmVjdGlvbiwgZmxvYXQgcm91Z2huZXNzICkge1xcblxcdGZsb2F0IHJvdWdobmVzc1ZhbCA9IHJvdWdobmVzcyogY3ViZVVWX21heExvZHMzO1xcblxcdGZsb2F0IHIxID0gZmxvb3Iocm91Z2huZXNzVmFsKTtcXG5cXHRmbG9hdCByMiA9IHIxICsgMS4wO1xcblxcdGZsb2F0IHQgPSBmcmFjdChyb3VnaG5lc3NWYWwpO1xcblxcdHZlYzIgbWlwSW5mbyA9IE1pcExldmVsSW5mbyhyZWZsZWN0ZWREaXJlY3Rpb24sIHIxLCByb3VnaG5lc3MpO1xcblxcdGZsb2F0IHMgPSBtaXBJbmZvLnk7XFxuXFx0ZmxvYXQgbGV2ZWwwID0gbWlwSW5mby54O1xcblxcdGZsb2F0IGxldmVsMSA9IGxldmVsMCArIDEuMDtcXG5cXHRsZXZlbDEgPSBsZXZlbDEgPiA1LjAgPyA1LjAgOiBsZXZlbDE7XFxuXFx0bGV2ZWwwICs9IG1pbiggZmxvb3IoIHMgKyAwLjUgKSwgNS4wICk7XFxuXFx0dmVjMiB1dl8xMCA9IGdldEN1YmVVVihyZWZsZWN0ZWREaXJlY3Rpb24sIHIxLCBsZXZlbDApO1xcblxcdHZlYzQgY29sb3IxMCA9IGVudk1hcFRleGVsVG9MaW5lYXIodGV4dHVyZTJEKGVudk1hcCwgdXZfMTApKTtcXG5cXHR2ZWMyIHV2XzIwID0gZ2V0Q3ViZVVWKHJlZmxlY3RlZERpcmVjdGlvbiwgcjIsIGxldmVsMCk7XFxuXFx0dmVjNCBjb2xvcjIwID0gZW52TWFwVGV4ZWxUb0xpbmVhcih0ZXh0dXJlMkQoZW52TWFwLCB1dl8yMCkpO1xcblxcdHZlYzQgcmVzdWx0ID0gbWl4KGNvbG9yMTAsIGNvbG9yMjAsIHQpO1xcblxcdHJldHVybiB2ZWM0KHJlc3VsdC5yZ2IsIDEuMCk7XFxufVxcbiNlbmRpZlxcblwiO1xuXG52YXIgZGVmYXVsdG5vcm1hbF92ZXJ0ZXggPSBcIiNpZmRlZiBGTElQX1NJREVEXFxuXFx0b2JqZWN0Tm9ybWFsID0gLW9iamVjdE5vcm1hbDtcXG4jZW5kaWZcXG52ZWMzIHRyYW5zZm9ybWVkTm9ybWFsID0gbm9ybWFsTWF0cml4ICogb2JqZWN0Tm9ybWFsO1xcblwiO1xuXG52YXIgZGlzcGxhY2VtZW50bWFwX3BhcnNfdmVydGV4ID0gXCIjaWZkZWYgVVNFX0RJU1BMQUNFTUVOVE1BUFxcblxcdHVuaWZvcm0gc2FtcGxlcjJEIGRpc3BsYWNlbWVudE1hcDtcXG5cXHR1bmlmb3JtIGZsb2F0IGRpc3BsYWNlbWVudFNjYWxlO1xcblxcdHVuaWZvcm0gZmxvYXQgZGlzcGxhY2VtZW50QmlhcztcXG4jZW5kaWZcXG5cIjtcblxudmFyIGRpc3BsYWNlbWVudG1hcF92ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfRElTUExBQ0VNRU5UTUFQXFxuXFx0dHJhbnNmb3JtZWQgKz0gbm9ybWFsICogKCB0ZXh0dXJlMkQoIGRpc3BsYWNlbWVudE1hcCwgdXYgKS54ICogZGlzcGxhY2VtZW50U2NhbGUgKyBkaXNwbGFjZW1lbnRCaWFzICk7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBlbWlzc2l2ZW1hcF9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9FTUlTU0lWRU1BUFxcblxcdHZlYzQgZW1pc3NpdmVDb2xvciA9IHRleHR1cmUyRCggZW1pc3NpdmVNYXAsIHZVdiApO1xcblxcdGVtaXNzaXZlQ29sb3IucmdiID0gZW1pc3NpdmVNYXBUZXhlbFRvTGluZWFyKCBlbWlzc2l2ZUNvbG9yICkucmdiO1xcblxcdHRvdGFsRW1pc3NpdmVSYWRpYW5jZSAqPSBlbWlzc2l2ZUNvbG9yLnJnYjtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGVtaXNzaXZlbWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfRU1JU1NJVkVNQVBcXG5cXHR1bmlmb3JtIHNhbXBsZXIyRCBlbWlzc2l2ZU1hcDtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGVuY29kaW5nc19mcmFnbWVudCA9IFwiICBnbF9GcmFnQ29sb3IgPSBsaW5lYXJUb091dHB1dFRleGVsKCBnbF9GcmFnQ29sb3IgKTtcXG5cIjtcblxudmFyIGVuY29kaW5nc19wYXJzX2ZyYWdtZW50ID0gXCJcXG52ZWM0IExpbmVhclRvTGluZWFyKCBpbiB2ZWM0IHZhbHVlICkge1xcblxcdHJldHVybiB2YWx1ZTtcXG59XFxudmVjNCBHYW1tYVRvTGluZWFyKCBpbiB2ZWM0IHZhbHVlLCBpbiBmbG9hdCBnYW1tYUZhY3RvciApIHtcXG5cXHRyZXR1cm4gdmVjNCggcG93KCB2YWx1ZS54eXosIHZlYzMoIGdhbW1hRmFjdG9yICkgKSwgdmFsdWUudyApO1xcbn1cXG52ZWM0IExpbmVhclRvR2FtbWEoIGluIHZlYzQgdmFsdWUsIGluIGZsb2F0IGdhbW1hRmFjdG9yICkge1xcblxcdHJldHVybiB2ZWM0KCBwb3coIHZhbHVlLnh5eiwgdmVjMyggMS4wIC8gZ2FtbWFGYWN0b3IgKSApLCB2YWx1ZS53ICk7XFxufVxcbnZlYzQgc1JHQlRvTGluZWFyKCBpbiB2ZWM0IHZhbHVlICkge1xcblxcdHJldHVybiB2ZWM0KCBtaXgoIHBvdyggdmFsdWUucmdiICogMC45NDc4NjcyOTg2ICsgdmVjMyggMC4wNTIxMzI3MDE0ICksIHZlYzMoIDIuNCApICksIHZhbHVlLnJnYiAqIDAuMDc3Mzk5MzgwOCwgdmVjMyggbGVzc1RoYW5FcXVhbCggdmFsdWUucmdiLCB2ZWMzKCAwLjA0MDQ1ICkgKSApICksIHZhbHVlLncgKTtcXG59XFxudmVjNCBMaW5lYXJUb3NSR0IoIGluIHZlYzQgdmFsdWUgKSB7XFxuXFx0cmV0dXJuIHZlYzQoIG1peCggcG93KCB2YWx1ZS5yZ2IsIHZlYzMoIDAuNDE2NjYgKSApICogMS4wNTUgLSB2ZWMzKCAwLjA1NSApLCB2YWx1ZS5yZ2IgKiAxMi45MiwgdmVjMyggbGVzc1RoYW5FcXVhbCggdmFsdWUucmdiLCB2ZWMzKCAwLjAwMzEzMDggKSApICkgKSwgdmFsdWUudyApO1xcbn1cXG52ZWM0IFJHQkVUb0xpbmVhciggaW4gdmVjNCB2YWx1ZSApIHtcXG5cXHRyZXR1cm4gdmVjNCggdmFsdWUucmdiICogZXhwMiggdmFsdWUuYSAqIDI1NS4wIC0gMTI4LjAgKSwgMS4wICk7XFxufVxcbnZlYzQgTGluZWFyVG9SR0JFKCBpbiB2ZWM0IHZhbHVlICkge1xcblxcdGZsb2F0IG1heENvbXBvbmVudCA9IG1heCggbWF4KCB2YWx1ZS5yLCB2YWx1ZS5nICksIHZhbHVlLmIgKTtcXG5cXHRmbG9hdCBmRXhwID0gY2xhbXAoIGNlaWwoIGxvZzIoIG1heENvbXBvbmVudCApICksIC0xMjguMCwgMTI3LjAgKTtcXG5cXHRyZXR1cm4gdmVjNCggdmFsdWUucmdiIC8gZXhwMiggZkV4cCApLCAoIGZFeHAgKyAxMjguMCApIC8gMjU1LjAgKTtcXG59XFxudmVjNCBSR0JNVG9MaW5lYXIoIGluIHZlYzQgdmFsdWUsIGluIGZsb2F0IG1heFJhbmdlICkge1xcblxcdHJldHVybiB2ZWM0KCB2YWx1ZS54eXogKiB2YWx1ZS53ICogbWF4UmFuZ2UsIDEuMCApO1xcbn1cXG52ZWM0IExpbmVhclRvUkdCTSggaW4gdmVjNCB2YWx1ZSwgaW4gZmxvYXQgbWF4UmFuZ2UgKSB7XFxuXFx0ZmxvYXQgbWF4UkdCID0gbWF4KCB2YWx1ZS54LCBtYXgoIHZhbHVlLmcsIHZhbHVlLmIgKSApO1xcblxcdGZsb2F0IE0gICAgICA9IGNsYW1wKCBtYXhSR0IgLyBtYXhSYW5nZSwgMC4wLCAxLjAgKTtcXG5cXHRNICAgICAgICAgICAgPSBjZWlsKCBNICogMjU1LjAgKSAvIDI1NS4wO1xcblxcdHJldHVybiB2ZWM0KCB2YWx1ZS5yZ2IgLyAoIE0gKiBtYXhSYW5nZSApLCBNICk7XFxufVxcbnZlYzQgUkdCRFRvTGluZWFyKCBpbiB2ZWM0IHZhbHVlLCBpbiBmbG9hdCBtYXhSYW5nZSApIHtcXG5cXHRyZXR1cm4gdmVjNCggdmFsdWUucmdiICogKCAoIG1heFJhbmdlIC8gMjU1LjAgKSAvIHZhbHVlLmEgKSwgMS4wICk7XFxufVxcbnZlYzQgTGluZWFyVG9SR0JEKCBpbiB2ZWM0IHZhbHVlLCBpbiBmbG9hdCBtYXhSYW5nZSApIHtcXG5cXHRmbG9hdCBtYXhSR0IgPSBtYXgoIHZhbHVlLngsIG1heCggdmFsdWUuZywgdmFsdWUuYiApICk7XFxuXFx0ZmxvYXQgRCAgICAgID0gbWF4KCBtYXhSYW5nZSAvIG1heFJHQiwgMS4wICk7XFxuXFx0RCAgICAgICAgICAgID0gbWluKCBmbG9vciggRCApIC8gMjU1LjAsIDEuMCApO1xcblxcdHJldHVybiB2ZWM0KCB2YWx1ZS5yZ2IgKiAoIEQgKiAoIDI1NS4wIC8gbWF4UmFuZ2UgKSApLCBEICk7XFxufVxcbmNvbnN0IG1hdDMgY0xvZ0x1dk0gPSBtYXQzKCAwLjIyMDksIDAuMzM5MCwgMC40MTg0LCAwLjExMzgsIDAuNjc4MCwgMC43MzE5LCAwLjAxMDIsIDAuMTEzMCwgMC4yOTY5ICk7XFxudmVjNCBMaW5lYXJUb0xvZ0x1diggaW4gdmVjNCB2YWx1ZSApICB7XFxuXFx0dmVjMyBYcF9ZX1hZWnAgPSB2YWx1ZS5yZ2IgKiBjTG9nTHV2TTtcXG5cXHRYcF9ZX1hZWnAgPSBtYXgoWHBfWV9YWVpwLCB2ZWMzKDFlLTYsIDFlLTYsIDFlLTYpKTtcXG5cXHR2ZWM0IHZSZXN1bHQ7XFxuXFx0dlJlc3VsdC54eSA9IFhwX1lfWFlacC54eSAvIFhwX1lfWFlacC56O1xcblxcdGZsb2F0IExlID0gMi4wICogbG9nMihYcF9ZX1hZWnAueSkgKyAxMjcuMDtcXG5cXHR2UmVzdWx0LncgPSBmcmFjdChMZSk7XFxuXFx0dlJlc3VsdC56ID0gKExlIC0gKGZsb29yKHZSZXN1bHQudyoyNTUuMCkpLzI1NS4wKS8yNTUuMDtcXG5cXHRyZXR1cm4gdlJlc3VsdDtcXG59XFxuY29uc3QgbWF0MyBjTG9nTHV2SW52ZXJzZU0gPSBtYXQzKCA2LjAwMTQsIC0yLjcwMDgsIC0xLjc5OTYsIC0xLjMzMjAsIDMuMTAyOSwgLTUuNzcyMSwgMC4zMDA4LCAtMS4wODgyLCA1LjYyNjggKTtcXG52ZWM0IExvZ0x1dlRvTGluZWFyKCBpbiB2ZWM0IHZhbHVlICkge1xcblxcdGZsb2F0IExlID0gdmFsdWUueiAqIDI1NS4wICsgdmFsdWUudztcXG5cXHR2ZWMzIFhwX1lfWFlacDtcXG5cXHRYcF9ZX1hZWnAueSA9IGV4cDIoKExlIC0gMTI3LjApIC8gMi4wKTtcXG5cXHRYcF9ZX1hZWnAueiA9IFhwX1lfWFlacC55IC8gdmFsdWUueTtcXG5cXHRYcF9ZX1hZWnAueCA9IHZhbHVlLnggKiBYcF9ZX1hZWnAuejtcXG5cXHR2ZWMzIHZSR0IgPSBYcF9ZX1hZWnAucmdiICogY0xvZ0x1dkludmVyc2VNO1xcblxcdHJldHVybiB2ZWM0KCBtYXgodlJHQiwgMC4wKSwgMS4wICk7XFxufVxcblwiO1xuXG52YXIgZW52bWFwX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0VOVk1BUFxcblxcdCNpZiBkZWZpbmVkKCBVU0VfQlVNUE1BUCApIHx8IGRlZmluZWQoIFVTRV9OT1JNQUxNQVAgKSB8fCBkZWZpbmVkKCBQSE9ORyApXFxuXFx0XFx0dmVjMyBjYW1lcmFUb1ZlcnRleCA9IG5vcm1hbGl6ZSggdldvcmxkUG9zaXRpb24gLSBjYW1lcmFQb3NpdGlvbiApO1xcblxcdFxcdHZlYzMgd29ybGROb3JtYWwgPSBpbnZlcnNlVHJhbnNmb3JtRGlyZWN0aW9uKCBub3JtYWwsIHZpZXdNYXRyaXggKTtcXG5cXHRcXHQjaWZkZWYgRU5WTUFQX01PREVfUkVGTEVDVElPTlxcblxcdFxcdFxcdHZlYzMgcmVmbGVjdFZlYyA9IHJlZmxlY3QoIGNhbWVyYVRvVmVydGV4LCB3b3JsZE5vcm1hbCApO1xcblxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0dmVjMyByZWZsZWN0VmVjID0gcmVmcmFjdCggY2FtZXJhVG9WZXJ0ZXgsIHdvcmxkTm9ybWFsLCByZWZyYWN0aW9uUmF0aW8gKTtcXG5cXHRcXHQjZW5kaWZcXG5cXHQjZWxzZVxcblxcdFxcdHZlYzMgcmVmbGVjdFZlYyA9IHZSZWZsZWN0O1xcblxcdCNlbmRpZlxcblxcdCNpZmRlZiBFTlZNQVBfVFlQRV9DVUJFXFxuXFx0XFx0dmVjNCBlbnZDb2xvciA9IHRleHR1cmVDdWJlKCBlbnZNYXAsIGZsaXBOb3JtYWwgKiB2ZWMzKCBmbGlwRW52TWFwICogcmVmbGVjdFZlYy54LCByZWZsZWN0VmVjLnl6ICkgKTtcXG5cXHQjZWxpZiBkZWZpbmVkKCBFTlZNQVBfVFlQRV9FUVVJUkVDIClcXG5cXHRcXHR2ZWMyIHNhbXBsZVVWO1xcblxcdFxcdHNhbXBsZVVWLnkgPSBzYXR1cmF0ZSggZmxpcE5vcm1hbCAqIHJlZmxlY3RWZWMueSAqIDAuNSArIDAuNSApO1xcblxcdFxcdHNhbXBsZVVWLnggPSBhdGFuKCBmbGlwTm9ybWFsICogcmVmbGVjdFZlYy56LCBmbGlwTm9ybWFsICogcmVmbGVjdFZlYy54ICkgKiBSRUNJUFJPQ0FMX1BJMiArIDAuNTtcXG5cXHRcXHR2ZWM0IGVudkNvbG9yID0gdGV4dHVyZTJEKCBlbnZNYXAsIHNhbXBsZVVWICk7XFxuXFx0I2VsaWYgZGVmaW5lZCggRU5WTUFQX1RZUEVfU1BIRVJFIClcXG5cXHRcXHR2ZWMzIHJlZmxlY3RWaWV3ID0gZmxpcE5vcm1hbCAqIG5vcm1hbGl6ZSggKCB2aWV3TWF0cml4ICogdmVjNCggcmVmbGVjdFZlYywgMC4wICkgKS54eXogKyB2ZWMzKCAwLjAsIDAuMCwgMS4wICkgKTtcXG5cXHRcXHR2ZWM0IGVudkNvbG9yID0gdGV4dHVyZTJEKCBlbnZNYXAsIHJlZmxlY3RWaWV3Lnh5ICogMC41ICsgMC41ICk7XFxuXFx0I2Vsc2VcXG5cXHRcXHR2ZWM0IGVudkNvbG9yID0gdmVjNCggMC4wICk7XFxuXFx0I2VuZGlmXFxuXFx0ZW52Q29sb3IgPSBlbnZNYXBUZXhlbFRvTGluZWFyKCBlbnZDb2xvciApO1xcblxcdCNpZmRlZiBFTlZNQVBfQkxFTkRJTkdfTVVMVElQTFlcXG5cXHRcXHRvdXRnb2luZ0xpZ2h0ID0gbWl4KCBvdXRnb2luZ0xpZ2h0LCBvdXRnb2luZ0xpZ2h0ICogZW52Q29sb3IueHl6LCBzcGVjdWxhclN0cmVuZ3RoICogcmVmbGVjdGl2aXR5ICk7XFxuXFx0I2VsaWYgZGVmaW5lZCggRU5WTUFQX0JMRU5ESU5HX01JWCApXFxuXFx0XFx0b3V0Z29pbmdMaWdodCA9IG1peCggb3V0Z29pbmdMaWdodCwgZW52Q29sb3IueHl6LCBzcGVjdWxhclN0cmVuZ3RoICogcmVmbGVjdGl2aXR5ICk7XFxuXFx0I2VsaWYgZGVmaW5lZCggRU5WTUFQX0JMRU5ESU5HX0FERCApXFxuXFx0XFx0b3V0Z29pbmdMaWdodCArPSBlbnZDb2xvci54eXogKiBzcGVjdWxhclN0cmVuZ3RoICogcmVmbGVjdGl2aXR5O1xcblxcdCNlbmRpZlxcbiNlbmRpZlxcblwiO1xuXG52YXIgZW52bWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZiBkZWZpbmVkKCBVU0VfRU5WTUFQICkgfHwgZGVmaW5lZCggUEhZU0lDQUwgKVxcblxcdHVuaWZvcm0gZmxvYXQgcmVmbGVjdGl2aXR5O1xcblxcdHVuaWZvcm0gZmxvYXQgZW52TWFwSW50ZW5zaXR5O1xcbiNlbmRpZlxcbiNpZmRlZiBVU0VfRU5WTUFQXFxuXFx0I2lmICEgZGVmaW5lZCggUEhZU0lDQUwgKSAmJiAoIGRlZmluZWQoIFVTRV9CVU1QTUFQICkgfHwgZGVmaW5lZCggVVNFX05PUk1BTE1BUCApIHx8IGRlZmluZWQoIFBIT05HICkgKVxcblxcdFxcdHZhcnlpbmcgdmVjMyB2V29ybGRQb3NpdGlvbjtcXG5cXHQjZW5kaWZcXG5cXHQjaWZkZWYgRU5WTUFQX1RZUEVfQ1VCRVxcblxcdFxcdHVuaWZvcm0gc2FtcGxlckN1YmUgZW52TWFwO1xcblxcdCNlbHNlXFxuXFx0XFx0dW5pZm9ybSBzYW1wbGVyMkQgZW52TWFwO1xcblxcdCNlbmRpZlxcblxcdHVuaWZvcm0gZmxvYXQgZmxpcEVudk1hcDtcXG5cXHQjaWYgZGVmaW5lZCggVVNFX0JVTVBNQVAgKSB8fCBkZWZpbmVkKCBVU0VfTk9STUFMTUFQICkgfHwgZGVmaW5lZCggUEhPTkcgKSB8fCBkZWZpbmVkKCBQSFlTSUNBTCApXFxuXFx0XFx0dW5pZm9ybSBmbG9hdCByZWZyYWN0aW9uUmF0aW87XFxuXFx0I2Vsc2VcXG5cXHRcXHR2YXJ5aW5nIHZlYzMgdlJlZmxlY3Q7XFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBlbnZtYXBfcGFyc192ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfRU5WTUFQXFxuXFx0I2lmIGRlZmluZWQoIFVTRV9CVU1QTUFQICkgfHwgZGVmaW5lZCggVVNFX05PUk1BTE1BUCApIHx8IGRlZmluZWQoIFBIT05HIClcXG5cXHRcXHR2YXJ5aW5nIHZlYzMgdldvcmxkUG9zaXRpb247XFxuXFx0I2Vsc2VcXG5cXHRcXHR2YXJ5aW5nIHZlYzMgdlJlZmxlY3Q7XFxuXFx0XFx0dW5pZm9ybSBmbG9hdCByZWZyYWN0aW9uUmF0aW87XFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBlbnZtYXBfdmVydGV4ID0gXCIjaWZkZWYgVVNFX0VOVk1BUFxcblxcdCNpZiBkZWZpbmVkKCBVU0VfQlVNUE1BUCApIHx8IGRlZmluZWQoIFVTRV9OT1JNQUxNQVAgKSB8fCBkZWZpbmVkKCBQSE9ORyApXFxuXFx0XFx0dldvcmxkUG9zaXRpb24gPSB3b3JsZFBvc2l0aW9uLnh5ejtcXG5cXHQjZWxzZVxcblxcdFxcdHZlYzMgY2FtZXJhVG9WZXJ0ZXggPSBub3JtYWxpemUoIHdvcmxkUG9zaXRpb24ueHl6IC0gY2FtZXJhUG9zaXRpb24gKTtcXG5cXHRcXHR2ZWMzIHdvcmxkTm9ybWFsID0gaW52ZXJzZVRyYW5zZm9ybURpcmVjdGlvbiggdHJhbnNmb3JtZWROb3JtYWwsIHZpZXdNYXRyaXggKTtcXG5cXHRcXHQjaWZkZWYgRU5WTUFQX01PREVfUkVGTEVDVElPTlxcblxcdFxcdFxcdHZSZWZsZWN0ID0gcmVmbGVjdCggY2FtZXJhVG9WZXJ0ZXgsIHdvcmxkTm9ybWFsICk7XFxuXFx0XFx0I2Vsc2VcXG5cXHRcXHRcXHR2UmVmbGVjdCA9IHJlZnJhY3QoIGNhbWVyYVRvVmVydGV4LCB3b3JsZE5vcm1hbCwgcmVmcmFjdGlvblJhdGlvICk7XFxuXFx0XFx0I2VuZGlmXFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBmb2dfdmVydGV4ID0gXCJcXG4jaWZkZWYgVVNFX0ZPR1xcbmZvZ0RlcHRoID0gLW12UG9zaXRpb24uejtcXG4jZW5kaWZcIjtcblxudmFyIGZvZ19wYXJzX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9GT0dcXG4gIHZhcnlpbmcgZmxvYXQgZm9nRGVwdGg7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBmb2dfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfRk9HXFxuXFx0I2lmZGVmIEZPR19FWFAyXFxuXFx0XFx0ZmxvYXQgZm9nRmFjdG9yID0gd2hpdGVDb21wbGltZW50KCBleHAyKCAtIGZvZ0RlbnNpdHkgKiBmb2dEZW5zaXR5ICogZm9nRGVwdGggKiBmb2dEZXB0aCAqIExPRzIgKSApO1xcblxcdCNlbHNlXFxuXFx0XFx0ZmxvYXQgZm9nRmFjdG9yID0gc21vb3Roc3RlcCggZm9nTmVhciwgZm9nRmFyLCBmb2dEZXB0aCApO1xcblxcdCNlbmRpZlxcblxcdGdsX0ZyYWdDb2xvci5yZ2IgPSBtaXgoIGdsX0ZyYWdDb2xvci5yZ2IsIGZvZ0NvbG9yLCBmb2dGYWN0b3IgKTtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGZvZ19wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0ZPR1xcblxcdHVuaWZvcm0gdmVjMyBmb2dDb2xvcjtcXG5cXHR2YXJ5aW5nIGZsb2F0IGZvZ0RlcHRoO1xcblxcdCNpZmRlZiBGT0dfRVhQMlxcblxcdFxcdHVuaWZvcm0gZmxvYXQgZm9nRGVuc2l0eTtcXG5cXHQjZWxzZVxcblxcdFxcdHVuaWZvcm0gZmxvYXQgZm9nTmVhcjtcXG5cXHRcXHR1bmlmb3JtIGZsb2F0IGZvZ0ZhcjtcXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIGdyYWRpZW50bWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBUT09OXFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgZ3JhZGllbnRNYXA7XFxuXFx0dmVjMyBnZXRHcmFkaWVudElycmFkaWFuY2UoIHZlYzMgbm9ybWFsLCB2ZWMzIGxpZ2h0RGlyZWN0aW9uICkge1xcblxcdFxcdGZsb2F0IGRvdE5MID0gZG90KCBub3JtYWwsIGxpZ2h0RGlyZWN0aW9uICk7XFxuXFx0XFx0dmVjMiBjb29yZCA9IHZlYzIoIGRvdE5MICogMC41ICsgMC41LCAwLjAgKTtcXG5cXHRcXHQjaWZkZWYgVVNFX0dSQURJRU5UTUFQXFxuXFx0XFx0XFx0cmV0dXJuIHRleHR1cmUyRCggZ3JhZGllbnRNYXAsIGNvb3JkICkucmdiO1xcblxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0cmV0dXJuICggY29vcmQueCA8IDAuNyApID8gdmVjMyggMC43ICkgOiB2ZWMzKCAxLjAgKTtcXG5cXHRcXHQjZW5kaWZcXG5cXHR9XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBsaWdodG1hcF9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9MSUdIVE1BUFxcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSArPSBQSSAqIHRleHR1cmUyRCggbGlnaHRNYXAsIHZVdjIgKS54eXogKiBsaWdodE1hcEludGVuc2l0eTtcXG4jZW5kaWZcXG5cIjtcblxudmFyIGxpZ2h0bWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfTElHSFRNQVBcXG5cXHR1bmlmb3JtIHNhbXBsZXIyRCBsaWdodE1hcDtcXG5cXHR1bmlmb3JtIGZsb2F0IGxpZ2h0TWFwSW50ZW5zaXR5O1xcbiNlbmRpZlwiO1xuXG52YXIgbGlnaHRzX2xhbWJlcnRfdmVydGV4ID0gXCJ2ZWMzIGRpZmZ1c2UgPSB2ZWMzKCAxLjAgKTtcXG5HZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5O1xcbmdlb21ldHJ5LnBvc2l0aW9uID0gbXZQb3NpdGlvbi54eXo7XFxuZ2VvbWV0cnkubm9ybWFsID0gbm9ybWFsaXplKCB0cmFuc2Zvcm1lZE5vcm1hbCApO1xcbmdlb21ldHJ5LnZpZXdEaXIgPSBub3JtYWxpemUoIC1tdlBvc2l0aW9uLnh5eiApO1xcbkdlb21ldHJpY0NvbnRleHQgYmFja0dlb21ldHJ5O1xcbmJhY2tHZW9tZXRyeS5wb3NpdGlvbiA9IGdlb21ldHJ5LnBvc2l0aW9uO1xcbmJhY2tHZW9tZXRyeS5ub3JtYWwgPSAtZ2VvbWV0cnkubm9ybWFsO1xcbmJhY2tHZW9tZXRyeS52aWV3RGlyID0gZ2VvbWV0cnkudmlld0RpcjtcXG52TGlnaHRGcm9udCA9IHZlYzMoIDAuMCApO1xcbiNpZmRlZiBET1VCTEVfU0lERURcXG5cXHR2TGlnaHRCYWNrID0gdmVjMyggMC4wICk7XFxuI2VuZGlmXFxuSW5jaWRlbnRMaWdodCBkaXJlY3RMaWdodDtcXG5mbG9hdCBkb3ROTDtcXG52ZWMzIGRpcmVjdExpZ2h0Q29sb3JfRGlmZnVzZTtcXG4jaWYgTlVNX1BPSU5UX0xJR0hUUyA+IDBcXG5cXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fUE9JTlRfTElHSFRTOyBpICsrICkge1xcblxcdFxcdGdldFBvaW50RGlyZWN0TGlnaHRJcnJhZGlhbmNlKCBwb2ludExpZ2h0c1sgaSBdLCBnZW9tZXRyeSwgZGlyZWN0TGlnaHQgKTtcXG5cXHRcXHRkb3ROTCA9IGRvdCggZ2VvbWV0cnkubm9ybWFsLCBkaXJlY3RMaWdodC5kaXJlY3Rpb24gKTtcXG5cXHRcXHRkaXJlY3RMaWdodENvbG9yX0RpZmZ1c2UgPSBQSSAqIGRpcmVjdExpZ2h0LmNvbG9yO1xcblxcdFxcdHZMaWdodEZyb250ICs9IHNhdHVyYXRlKCBkb3ROTCApICogZGlyZWN0TGlnaHRDb2xvcl9EaWZmdXNlO1xcblxcdFxcdCNpZmRlZiBET1VCTEVfU0lERURcXG5cXHRcXHRcXHR2TGlnaHRCYWNrICs9IHNhdHVyYXRlKCAtZG90TkwgKSAqIGRpcmVjdExpZ2h0Q29sb3JfRGlmZnVzZTtcXG5cXHRcXHQjZW5kaWZcXG5cXHR9XFxuI2VuZGlmXFxuI2lmIE5VTV9TUE9UX0xJR0hUUyA+IDBcXG5cXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fU1BPVF9MSUdIVFM7IGkgKysgKSB7XFxuXFx0XFx0Z2V0U3BvdERpcmVjdExpZ2h0SXJyYWRpYW5jZSggc3BvdExpZ2h0c1sgaSBdLCBnZW9tZXRyeSwgZGlyZWN0TGlnaHQgKTtcXG5cXHRcXHRkb3ROTCA9IGRvdCggZ2VvbWV0cnkubm9ybWFsLCBkaXJlY3RMaWdodC5kaXJlY3Rpb24gKTtcXG5cXHRcXHRkaXJlY3RMaWdodENvbG9yX0RpZmZ1c2UgPSBQSSAqIGRpcmVjdExpZ2h0LmNvbG9yO1xcblxcdFxcdHZMaWdodEZyb250ICs9IHNhdHVyYXRlKCBkb3ROTCApICogZGlyZWN0TGlnaHRDb2xvcl9EaWZmdXNlO1xcblxcdFxcdCNpZmRlZiBET1VCTEVfU0lERURcXG5cXHRcXHRcXHR2TGlnaHRCYWNrICs9IHNhdHVyYXRlKCAtZG90TkwgKSAqIGRpcmVjdExpZ2h0Q29sb3JfRGlmZnVzZTtcXG5cXHRcXHQjZW5kaWZcXG5cXHR9XFxuI2VuZGlmXFxuI2lmIE5VTV9ESVJfTElHSFRTID4gMFxcblxcdGZvciAoIGludCBpID0gMDsgaSA8IE5VTV9ESVJfTElHSFRTOyBpICsrICkge1xcblxcdFxcdGdldERpcmVjdGlvbmFsRGlyZWN0TGlnaHRJcnJhZGlhbmNlKCBkaXJlY3Rpb25hbExpZ2h0c1sgaSBdLCBnZW9tZXRyeSwgZGlyZWN0TGlnaHQgKTtcXG5cXHRcXHRkb3ROTCA9IGRvdCggZ2VvbWV0cnkubm9ybWFsLCBkaXJlY3RMaWdodC5kaXJlY3Rpb24gKTtcXG5cXHRcXHRkaXJlY3RMaWdodENvbG9yX0RpZmZ1c2UgPSBQSSAqIGRpcmVjdExpZ2h0LmNvbG9yO1xcblxcdFxcdHZMaWdodEZyb250ICs9IHNhdHVyYXRlKCBkb3ROTCApICogZGlyZWN0TGlnaHRDb2xvcl9EaWZmdXNlO1xcblxcdFxcdCNpZmRlZiBET1VCTEVfU0lERURcXG5cXHRcXHRcXHR2TGlnaHRCYWNrICs9IHNhdHVyYXRlKCAtZG90TkwgKSAqIGRpcmVjdExpZ2h0Q29sb3JfRGlmZnVzZTtcXG5cXHRcXHQjZW5kaWZcXG5cXHR9XFxuI2VuZGlmXFxuI2lmIE5VTV9IRU1JX0xJR0hUUyA+IDBcXG5cXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fSEVNSV9MSUdIVFM7IGkgKysgKSB7XFxuXFx0XFx0dkxpZ2h0RnJvbnQgKz0gZ2V0SGVtaXNwaGVyZUxpZ2h0SXJyYWRpYW5jZSggaGVtaXNwaGVyZUxpZ2h0c1sgaSBdLCBnZW9tZXRyeSApO1xcblxcdFxcdCNpZmRlZiBET1VCTEVfU0lERURcXG5cXHRcXHRcXHR2TGlnaHRCYWNrICs9IGdldEhlbWlzcGhlcmVMaWdodElycmFkaWFuY2UoIGhlbWlzcGhlcmVMaWdodHNbIGkgXSwgYmFja0dlb21ldHJ5ICk7XFxuXFx0XFx0I2VuZGlmXFxuXFx0fVxcbiNlbmRpZlxcblwiO1xuXG52YXIgbGlnaHRzX3BhcnMgPSBcInVuaWZvcm0gdmVjMyBhbWJpZW50TGlnaHRDb2xvcjtcXG52ZWMzIGdldEFtYmllbnRMaWdodElycmFkaWFuY2UoIGNvbnN0IGluIHZlYzMgYW1iaWVudExpZ2h0Q29sb3IgKSB7XFxuXFx0dmVjMyBpcnJhZGlhbmNlID0gYW1iaWVudExpZ2h0Q29sb3I7XFxuXFx0I2lmbmRlZiBQSFlTSUNBTExZX0NPUlJFQ1RfTElHSFRTXFxuXFx0XFx0aXJyYWRpYW5jZSAqPSBQSTtcXG5cXHQjZW5kaWZcXG5cXHRyZXR1cm4gaXJyYWRpYW5jZTtcXG59XFxuI2lmIE5VTV9ESVJfTElHSFRTID4gMFxcblxcdHN0cnVjdCBEaXJlY3Rpb25hbExpZ2h0IHtcXG5cXHRcXHR2ZWMzIGRpcmVjdGlvbjtcXG5cXHRcXHR2ZWMzIGNvbG9yO1xcblxcdFxcdGludCBzaGFkb3c7XFxuXFx0XFx0ZmxvYXQgc2hhZG93QmlhcztcXG5cXHRcXHRmbG9hdCBzaGFkb3dSYWRpdXM7XFxuXFx0XFx0dmVjMiBzaGFkb3dNYXBTaXplO1xcblxcdH07XFxuXFx0dW5pZm9ybSBEaXJlY3Rpb25hbExpZ2h0IGRpcmVjdGlvbmFsTGlnaHRzWyBOVU1fRElSX0xJR0hUUyBdO1xcblxcdHZvaWQgZ2V0RGlyZWN0aW9uYWxEaXJlY3RMaWdodElycmFkaWFuY2UoIGNvbnN0IGluIERpcmVjdGlvbmFsTGlnaHQgZGlyZWN0aW9uYWxMaWdodCwgY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgb3V0IEluY2lkZW50TGlnaHQgZGlyZWN0TGlnaHQgKSB7XFxuXFx0XFx0ZGlyZWN0TGlnaHQuY29sb3IgPSBkaXJlY3Rpb25hbExpZ2h0LmNvbG9yO1xcblxcdFxcdGRpcmVjdExpZ2h0LmRpcmVjdGlvbiA9IGRpcmVjdGlvbmFsTGlnaHQuZGlyZWN0aW9uO1xcblxcdFxcdGRpcmVjdExpZ2h0LnZpc2libGUgPSB0cnVlO1xcblxcdH1cXG4jZW5kaWZcXG4jaWYgTlVNX1BPSU5UX0xJR0hUUyA+IDBcXG5cXHRzdHJ1Y3QgUG9pbnRMaWdodCB7XFxuXFx0XFx0dmVjMyBwb3NpdGlvbjtcXG5cXHRcXHR2ZWMzIGNvbG9yO1xcblxcdFxcdGZsb2F0IGRpc3RhbmNlO1xcblxcdFxcdGZsb2F0IGRlY2F5O1xcblxcdFxcdGludCBzaGFkb3c7XFxuXFx0XFx0ZmxvYXQgc2hhZG93QmlhcztcXG5cXHRcXHRmbG9hdCBzaGFkb3dSYWRpdXM7XFxuXFx0XFx0dmVjMiBzaGFkb3dNYXBTaXplO1xcblxcdH07XFxuXFx0dW5pZm9ybSBQb2ludExpZ2h0IHBvaW50TGlnaHRzWyBOVU1fUE9JTlRfTElHSFRTIF07XFxuXFx0dm9pZCBnZXRQb2ludERpcmVjdExpZ2h0SXJyYWRpYW5jZSggY29uc3QgaW4gUG9pbnRMaWdodCBwb2ludExpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBvdXQgSW5jaWRlbnRMaWdodCBkaXJlY3RMaWdodCApIHtcXG5cXHRcXHR2ZWMzIGxWZWN0b3IgPSBwb2ludExpZ2h0LnBvc2l0aW9uIC0gZ2VvbWV0cnkucG9zaXRpb247XFxuXFx0XFx0ZGlyZWN0TGlnaHQuZGlyZWN0aW9uID0gbm9ybWFsaXplKCBsVmVjdG9yICk7XFxuXFx0XFx0ZmxvYXQgbGlnaHREaXN0YW5jZSA9IGxlbmd0aCggbFZlY3RvciApO1xcblxcdFxcdGRpcmVjdExpZ2h0LmNvbG9yID0gcG9pbnRMaWdodC5jb2xvcjtcXG5cXHRcXHRkaXJlY3RMaWdodC5jb2xvciAqPSBwdW5jdHVhbExpZ2h0SW50ZW5zaXR5VG9JcnJhZGlhbmNlRmFjdG9yKCBsaWdodERpc3RhbmNlLCBwb2ludExpZ2h0LmRpc3RhbmNlLCBwb2ludExpZ2h0LmRlY2F5ICk7XFxuXFx0XFx0ZGlyZWN0TGlnaHQudmlzaWJsZSA9ICggZGlyZWN0TGlnaHQuY29sb3IgIT0gdmVjMyggMC4wICkgKTtcXG5cXHR9XFxuI2VuZGlmXFxuI2lmIE5VTV9TUE9UX0xJR0hUUyA+IDBcXG5cXHRzdHJ1Y3QgU3BvdExpZ2h0IHtcXG5cXHRcXHR2ZWMzIHBvc2l0aW9uO1xcblxcdFxcdHZlYzMgZGlyZWN0aW9uO1xcblxcdFxcdHZlYzMgY29sb3I7XFxuXFx0XFx0ZmxvYXQgZGlzdGFuY2U7XFxuXFx0XFx0ZmxvYXQgZGVjYXk7XFxuXFx0XFx0ZmxvYXQgY29uZUNvcztcXG5cXHRcXHRmbG9hdCBwZW51bWJyYUNvcztcXG5cXHRcXHRpbnQgc2hhZG93O1xcblxcdFxcdGZsb2F0IHNoYWRvd0JpYXM7XFxuXFx0XFx0ZmxvYXQgc2hhZG93UmFkaXVzO1xcblxcdFxcdHZlYzIgc2hhZG93TWFwU2l6ZTtcXG5cXHR9O1xcblxcdHVuaWZvcm0gU3BvdExpZ2h0IHNwb3RMaWdodHNbIE5VTV9TUE9UX0xJR0hUUyBdO1xcblxcdHZvaWQgZ2V0U3BvdERpcmVjdExpZ2h0SXJyYWRpYW5jZSggY29uc3QgaW4gU3BvdExpZ2h0IHNwb3RMaWdodCwgY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgb3V0IEluY2lkZW50TGlnaHQgZGlyZWN0TGlnaHQgICkge1xcblxcdFxcdHZlYzMgbFZlY3RvciA9IHNwb3RMaWdodC5wb3NpdGlvbiAtIGdlb21ldHJ5LnBvc2l0aW9uO1xcblxcdFxcdGRpcmVjdExpZ2h0LmRpcmVjdGlvbiA9IG5vcm1hbGl6ZSggbFZlY3RvciApO1xcblxcdFxcdGZsb2F0IGxpZ2h0RGlzdGFuY2UgPSBsZW5ndGgoIGxWZWN0b3IgKTtcXG5cXHRcXHRmbG9hdCBhbmdsZUNvcyA9IGRvdCggZGlyZWN0TGlnaHQuZGlyZWN0aW9uLCBzcG90TGlnaHQuZGlyZWN0aW9uICk7XFxuXFx0XFx0aWYgKCBhbmdsZUNvcyA+IHNwb3RMaWdodC5jb25lQ29zICkge1xcblxcdFxcdFxcdGZsb2F0IHNwb3RFZmZlY3QgPSBzbW9vdGhzdGVwKCBzcG90TGlnaHQuY29uZUNvcywgc3BvdExpZ2h0LnBlbnVtYnJhQ29zLCBhbmdsZUNvcyApO1xcblxcdFxcdFxcdGRpcmVjdExpZ2h0LmNvbG9yID0gc3BvdExpZ2h0LmNvbG9yO1xcblxcdFxcdFxcdGRpcmVjdExpZ2h0LmNvbG9yICo9IHNwb3RFZmZlY3QgKiBwdW5jdHVhbExpZ2h0SW50ZW5zaXR5VG9JcnJhZGlhbmNlRmFjdG9yKCBsaWdodERpc3RhbmNlLCBzcG90TGlnaHQuZGlzdGFuY2UsIHNwb3RMaWdodC5kZWNheSApO1xcblxcdFxcdFxcdGRpcmVjdExpZ2h0LnZpc2libGUgPSB0cnVlO1xcblxcdFxcdH0gZWxzZSB7XFxuXFx0XFx0XFx0ZGlyZWN0TGlnaHQuY29sb3IgPSB2ZWMzKCAwLjAgKTtcXG5cXHRcXHRcXHRkaXJlY3RMaWdodC52aXNpYmxlID0gZmFsc2U7XFxuXFx0XFx0fVxcblxcdH1cXG4jZW5kaWZcXG4jaWYgTlVNX1JFQ1RfQVJFQV9MSUdIVFMgPiAwXFxuXFx0c3RydWN0IFJlY3RBcmVhTGlnaHQge1xcblxcdFxcdHZlYzMgY29sb3I7XFxuXFx0XFx0dmVjMyBwb3NpdGlvbjtcXG5cXHRcXHR2ZWMzIGhhbGZXaWR0aDtcXG5cXHRcXHR2ZWMzIGhhbGZIZWlnaHQ7XFxuXFx0fTtcXG5cXHR1bmlmb3JtIHNhbXBsZXIyRCBsdGNNYXQ7XFx0dW5pZm9ybSBzYW1wbGVyMkQgbHRjTWFnO1xcblxcdHVuaWZvcm0gUmVjdEFyZWFMaWdodCByZWN0QXJlYUxpZ2h0c1sgTlVNX1JFQ1RfQVJFQV9MSUdIVFMgXTtcXG4jZW5kaWZcXG4jaWYgTlVNX0hFTUlfTElHSFRTID4gMFxcblxcdHN0cnVjdCBIZW1pc3BoZXJlTGlnaHQge1xcblxcdFxcdHZlYzMgZGlyZWN0aW9uO1xcblxcdFxcdHZlYzMgc2t5Q29sb3I7XFxuXFx0XFx0dmVjMyBncm91bmRDb2xvcjtcXG5cXHR9O1xcblxcdHVuaWZvcm0gSGVtaXNwaGVyZUxpZ2h0IGhlbWlzcGhlcmVMaWdodHNbIE5VTV9IRU1JX0xJR0hUUyBdO1xcblxcdHZlYzMgZ2V0SGVtaXNwaGVyZUxpZ2h0SXJyYWRpYW5jZSggY29uc3QgaW4gSGVtaXNwaGVyZUxpZ2h0IGhlbWlMaWdodCwgY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSApIHtcXG5cXHRcXHRmbG9hdCBkb3ROTCA9IGRvdCggZ2VvbWV0cnkubm9ybWFsLCBoZW1pTGlnaHQuZGlyZWN0aW9uICk7XFxuXFx0XFx0ZmxvYXQgaGVtaURpZmZ1c2VXZWlnaHQgPSAwLjUgKiBkb3ROTCArIDAuNTtcXG5cXHRcXHR2ZWMzIGlycmFkaWFuY2UgPSBtaXgoIGhlbWlMaWdodC5ncm91bmRDb2xvciwgaGVtaUxpZ2h0LnNreUNvbG9yLCBoZW1pRGlmZnVzZVdlaWdodCApO1xcblxcdFxcdCNpZm5kZWYgUEhZU0lDQUxMWV9DT1JSRUNUX0xJR0hUU1xcblxcdFxcdFxcdGlycmFkaWFuY2UgKj0gUEk7XFxuXFx0XFx0I2VuZGlmXFxuXFx0XFx0cmV0dXJuIGlycmFkaWFuY2U7XFxuXFx0fVxcbiNlbmRpZlxcbiNpZiBkZWZpbmVkKCBVU0VfRU5WTUFQICkgJiYgZGVmaW5lZCggUEhZU0lDQUwgKVxcblxcdHZlYzMgZ2V0TGlnaHRQcm9iZUluZGlyZWN0SXJyYWRpYW5jZSggY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgY29uc3QgaW4gaW50IG1heE1JUExldmVsICkge1xcblxcdFxcdHZlYzMgd29ybGROb3JtYWwgPSBpbnZlcnNlVHJhbnNmb3JtRGlyZWN0aW9uKCBnZW9tZXRyeS5ub3JtYWwsIHZpZXdNYXRyaXggKTtcXG5cXHRcXHQjaWZkZWYgRU5WTUFQX1RZUEVfQ1VCRVxcblxcdFxcdFxcdHZlYzMgcXVlcnlWZWMgPSB2ZWMzKCBmbGlwRW52TWFwICogd29ybGROb3JtYWwueCwgd29ybGROb3JtYWwueXogKTtcXG5cXHRcXHRcXHQjaWZkZWYgVEVYVFVSRV9MT0RfRVhUXFxuXFx0XFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHRleHR1cmVDdWJlTG9kRVhUKCBlbnZNYXAsIHF1ZXJ5VmVjLCBmbG9hdCggbWF4TUlQTGV2ZWwgKSApO1xcblxcdFxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHRleHR1cmVDdWJlKCBlbnZNYXAsIHF1ZXJ5VmVjLCBmbG9hdCggbWF4TUlQTGV2ZWwgKSApO1xcblxcdFxcdFxcdCNlbmRpZlxcblxcdFxcdFxcdGVudk1hcENvbG9yLnJnYiA9IGVudk1hcFRleGVsVG9MaW5lYXIoIGVudk1hcENvbG9yICkucmdiO1xcblxcdFxcdCNlbGlmIGRlZmluZWQoIEVOVk1BUF9UWVBFX0NVQkVfVVYgKVxcblxcdFxcdFxcdHZlYzMgcXVlcnlWZWMgPSB2ZWMzKCBmbGlwRW52TWFwICogd29ybGROb3JtYWwueCwgd29ybGROb3JtYWwueXogKTtcXG5cXHRcXHRcXHR2ZWM0IGVudk1hcENvbG9yID0gdGV4dHVyZUN1YmVVViggcXVlcnlWZWMsIDEuMCApO1xcblxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHZlYzQoIDAuMCApO1xcblxcdFxcdCNlbmRpZlxcblxcdFxcdHJldHVybiBQSSAqIGVudk1hcENvbG9yLnJnYiAqIGVudk1hcEludGVuc2l0eTtcXG5cXHR9XFxuXFx0ZmxvYXQgZ2V0U3BlY3VsYXJNSVBMZXZlbCggY29uc3QgaW4gZmxvYXQgYmxpbm5TaGluaW5lc3NFeHBvbmVudCwgY29uc3QgaW4gaW50IG1heE1JUExldmVsICkge1xcblxcdFxcdGZsb2F0IG1heE1JUExldmVsU2NhbGFyID0gZmxvYXQoIG1heE1JUExldmVsICk7XFxuXFx0XFx0ZmxvYXQgZGVzaXJlZE1JUExldmVsID0gbWF4TUlQTGV2ZWxTY2FsYXIgLSAwLjc5MjQ4IC0gMC41ICogbG9nMiggcG93MiggYmxpbm5TaGluaW5lc3NFeHBvbmVudCApICsgMS4wICk7XFxuXFx0XFx0cmV0dXJuIGNsYW1wKCBkZXNpcmVkTUlQTGV2ZWwsIDAuMCwgbWF4TUlQTGV2ZWxTY2FsYXIgKTtcXG5cXHR9XFxuXFx0dmVjMyBnZXRMaWdodFByb2JlSW5kaXJlY3RSYWRpYW5jZSggY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgY29uc3QgaW4gZmxvYXQgYmxpbm5TaGluaW5lc3NFeHBvbmVudCwgY29uc3QgaW4gaW50IG1heE1JUExldmVsICkge1xcblxcdFxcdCNpZmRlZiBFTlZNQVBfTU9ERV9SRUZMRUNUSU9OXFxuXFx0XFx0XFx0dmVjMyByZWZsZWN0VmVjID0gcmVmbGVjdCggLWdlb21ldHJ5LnZpZXdEaXIsIGdlb21ldHJ5Lm5vcm1hbCApO1xcblxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0dmVjMyByZWZsZWN0VmVjID0gcmVmcmFjdCggLWdlb21ldHJ5LnZpZXdEaXIsIGdlb21ldHJ5Lm5vcm1hbCwgcmVmcmFjdGlvblJhdGlvICk7XFxuXFx0XFx0I2VuZGlmXFxuXFx0XFx0cmVmbGVjdFZlYyA9IGludmVyc2VUcmFuc2Zvcm1EaXJlY3Rpb24oIHJlZmxlY3RWZWMsIHZpZXdNYXRyaXggKTtcXG5cXHRcXHRmbG9hdCBzcGVjdWxhck1JUExldmVsID0gZ2V0U3BlY3VsYXJNSVBMZXZlbCggYmxpbm5TaGluaW5lc3NFeHBvbmVudCwgbWF4TUlQTGV2ZWwgKTtcXG5cXHRcXHQjaWZkZWYgRU5WTUFQX1RZUEVfQ1VCRVxcblxcdFxcdFxcdHZlYzMgcXVlcnlSZWZsZWN0VmVjID0gdmVjMyggZmxpcEVudk1hcCAqIHJlZmxlY3RWZWMueCwgcmVmbGVjdFZlYy55eiApO1xcblxcdFxcdFxcdCNpZmRlZiBURVhUVVJFX0xPRF9FWFRcXG5cXHRcXHRcXHRcXHR2ZWM0IGVudk1hcENvbG9yID0gdGV4dHVyZUN1YmVMb2RFWFQoIGVudk1hcCwgcXVlcnlSZWZsZWN0VmVjLCBzcGVjdWxhck1JUExldmVsICk7XFxuXFx0XFx0XFx0I2Vsc2VcXG5cXHRcXHRcXHRcXHR2ZWM0IGVudk1hcENvbG9yID0gdGV4dHVyZUN1YmUoIGVudk1hcCwgcXVlcnlSZWZsZWN0VmVjLCBzcGVjdWxhck1JUExldmVsICk7XFxuXFx0XFx0XFx0I2VuZGlmXFxuXFx0XFx0XFx0ZW52TWFwQ29sb3IucmdiID0gZW52TWFwVGV4ZWxUb0xpbmVhciggZW52TWFwQ29sb3IgKS5yZ2I7XFxuXFx0XFx0I2VsaWYgZGVmaW5lZCggRU5WTUFQX1RZUEVfQ1VCRV9VViApXFxuXFx0XFx0XFx0dmVjMyBxdWVyeVJlZmxlY3RWZWMgPSB2ZWMzKCBmbGlwRW52TWFwICogcmVmbGVjdFZlYy54LCByZWZsZWN0VmVjLnl6ICk7XFxuXFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHRleHR1cmVDdWJlVVYocXVlcnlSZWZsZWN0VmVjLCBCbGlubkV4cG9uZW50VG9HR1hSb3VnaG5lc3MoYmxpbm5TaGluaW5lc3NFeHBvbmVudCkpO1xcblxcdFxcdCNlbGlmIGRlZmluZWQoIEVOVk1BUF9UWVBFX0VRVUlSRUMgKVxcblxcdFxcdFxcdHZlYzIgc2FtcGxlVVY7XFxuXFx0XFx0XFx0c2FtcGxlVVYueSA9IHNhdHVyYXRlKCByZWZsZWN0VmVjLnkgKiAwLjUgKyAwLjUgKTtcXG5cXHRcXHRcXHRzYW1wbGVVVi54ID0gYXRhbiggcmVmbGVjdFZlYy56LCByZWZsZWN0VmVjLnggKSAqIFJFQ0lQUk9DQUxfUEkyICsgMC41O1xcblxcdFxcdFxcdCNpZmRlZiBURVhUVVJFX0xPRF9FWFRcXG5cXHRcXHRcXHRcXHR2ZWM0IGVudk1hcENvbG9yID0gdGV4dHVyZTJETG9kRVhUKCBlbnZNYXAsIHNhbXBsZVVWLCBzcGVjdWxhck1JUExldmVsICk7XFxuXFx0XFx0XFx0I2Vsc2VcXG5cXHRcXHRcXHRcXHR2ZWM0IGVudk1hcENvbG9yID0gdGV4dHVyZTJEKCBlbnZNYXAsIHNhbXBsZVVWLCBzcGVjdWxhck1JUExldmVsICk7XFxuXFx0XFx0XFx0I2VuZGlmXFxuXFx0XFx0XFx0ZW52TWFwQ29sb3IucmdiID0gZW52TWFwVGV4ZWxUb0xpbmVhciggZW52TWFwQ29sb3IgKS5yZ2I7XFxuXFx0XFx0I2VsaWYgZGVmaW5lZCggRU5WTUFQX1RZUEVfU1BIRVJFIClcXG5cXHRcXHRcXHR2ZWMzIHJlZmxlY3RWaWV3ID0gbm9ybWFsaXplKCAoIHZpZXdNYXRyaXggKiB2ZWM0KCByZWZsZWN0VmVjLCAwLjAgKSApLnh5eiArIHZlYzMoIDAuMCwwLjAsMS4wICkgKTtcXG5cXHRcXHRcXHQjaWZkZWYgVEVYVFVSRV9MT0RfRVhUXFxuXFx0XFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHRleHR1cmUyRExvZEVYVCggZW52TWFwLCByZWZsZWN0Vmlldy54eSAqIDAuNSArIDAuNSwgc3BlY3VsYXJNSVBMZXZlbCApO1xcblxcdFxcdFxcdCNlbHNlXFxuXFx0XFx0XFx0XFx0dmVjNCBlbnZNYXBDb2xvciA9IHRleHR1cmUyRCggZW52TWFwLCByZWZsZWN0Vmlldy54eSAqIDAuNSArIDAuNSwgc3BlY3VsYXJNSVBMZXZlbCApO1xcblxcdFxcdFxcdCNlbmRpZlxcblxcdFxcdFxcdGVudk1hcENvbG9yLnJnYiA9IGVudk1hcFRleGVsVG9MaW5lYXIoIGVudk1hcENvbG9yICkucmdiO1xcblxcdFxcdCNlbmRpZlxcblxcdFxcdHJldHVybiBlbnZNYXBDb2xvci5yZ2IgKiBlbnZNYXBJbnRlbnNpdHk7XFxuXFx0fVxcbiNlbmRpZlxcblwiO1xuXG52YXIgbGlnaHRzX3Bob25nX2ZyYWdtZW50ID0gXCJCbGlublBob25nTWF0ZXJpYWwgbWF0ZXJpYWw7XFxubWF0ZXJpYWwuZGlmZnVzZUNvbG9yID0gZGlmZnVzZUNvbG9yLnJnYjtcXG5tYXRlcmlhbC5zcGVjdWxhckNvbG9yID0gc3BlY3VsYXI7XFxubWF0ZXJpYWwuc3BlY3VsYXJTaGluaW5lc3MgPSBzaGluaW5lc3M7XFxubWF0ZXJpYWwuc3BlY3VsYXJTdHJlbmd0aCA9IHNwZWN1bGFyU3RyZW5ndGg7XFxuXCI7XG5cbnZhciBsaWdodHNfcGhvbmdfcGFyc19mcmFnbWVudCA9IFwidmFyeWluZyB2ZWMzIHZWaWV3UG9zaXRpb247XFxuI2lmbmRlZiBGTEFUX1NIQURFRFxcblxcdHZhcnlpbmcgdmVjMyB2Tm9ybWFsO1xcbiNlbmRpZlxcbnN0cnVjdCBCbGlublBob25nTWF0ZXJpYWwge1xcblxcdHZlYzNcXHRkaWZmdXNlQ29sb3I7XFxuXFx0dmVjM1xcdHNwZWN1bGFyQ29sb3I7XFxuXFx0ZmxvYXRcXHRzcGVjdWxhclNoaW5pbmVzcztcXG5cXHRmbG9hdFxcdHNwZWN1bGFyU3RyZW5ndGg7XFxufTtcXG4jaWYgTlVNX1JFQ1RfQVJFQV9MSUdIVFMgPiAwXFxuXFx0dm9pZCBSRV9EaXJlY3RfUmVjdEFyZWFfQmxpbm5QaG9uZyggY29uc3QgaW4gUmVjdEFyZWFMaWdodCByZWN0QXJlYUxpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiBCbGlublBob25nTWF0ZXJpYWwgbWF0ZXJpYWwsIGlub3V0IFJlZmxlY3RlZExpZ2h0IHJlZmxlY3RlZExpZ2h0ICkge1xcblxcdFxcdHZlYzMgbm9ybWFsID0gZ2VvbWV0cnkubm9ybWFsO1xcblxcdFxcdHZlYzMgdmlld0RpciA9IGdlb21ldHJ5LnZpZXdEaXI7XFxuXFx0XFx0dmVjMyBwb3NpdGlvbiA9IGdlb21ldHJ5LnBvc2l0aW9uO1xcblxcdFxcdHZlYzMgbGlnaHRQb3MgPSByZWN0QXJlYUxpZ2h0LnBvc2l0aW9uO1xcblxcdFxcdHZlYzMgaGFsZldpZHRoID0gcmVjdEFyZWFMaWdodC5oYWxmV2lkdGg7XFxuXFx0XFx0dmVjMyBoYWxmSGVpZ2h0ID0gcmVjdEFyZWFMaWdodC5oYWxmSGVpZ2h0O1xcblxcdFxcdHZlYzMgbGlnaHRDb2xvciA9IHJlY3RBcmVhTGlnaHQuY29sb3I7XFxuXFx0XFx0ZmxvYXQgcm91Z2huZXNzID0gQmxpbm5FeHBvbmVudFRvR0dYUm91Z2huZXNzKCBtYXRlcmlhbC5zcGVjdWxhclNoaW5pbmVzcyApO1xcblxcdFxcdHZlYzMgcmVjdENvb3Jkc1sgNCBdO1xcblxcdFxcdHJlY3RDb29yZHNbIDAgXSA9IGxpZ2h0UG9zIC0gaGFsZldpZHRoIC0gaGFsZkhlaWdodDtcXHRcXHRyZWN0Q29vcmRzWyAxIF0gPSBsaWdodFBvcyArIGhhbGZXaWR0aCAtIGhhbGZIZWlnaHQ7XFxuXFx0XFx0cmVjdENvb3Jkc1sgMiBdID0gbGlnaHRQb3MgKyBoYWxmV2lkdGggKyBoYWxmSGVpZ2h0O1xcblxcdFxcdHJlY3RDb29yZHNbIDMgXSA9IGxpZ2h0UG9zIC0gaGFsZldpZHRoICsgaGFsZkhlaWdodDtcXG5cXHRcXHR2ZWMyIHV2ID0gTFRDX1V2KCBub3JtYWwsIHZpZXdEaXIsIHJvdWdobmVzcyApO1xcblxcdFxcdGZsb2F0IG5vcm0gPSB0ZXh0dXJlMkQoIGx0Y01hZywgdXYgKS5hO1xcblxcdFxcdHZlYzQgdCA9IHRleHR1cmUyRCggbHRjTWF0LCB1diApO1xcblxcdFxcdG1hdDMgbUludiA9IG1hdDMoXFxuXFx0XFx0XFx0dmVjMyggICAxLCAgIDAsIHQueSApLFxcblxcdFxcdFxcdHZlYzMoICAgMCwgdC56LCAgIDAgKSxcXG5cXHRcXHRcXHR2ZWMzKCB0LncsICAgMCwgdC54IClcXG5cXHRcXHQpO1xcblxcdFxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyICs9IGxpZ2h0Q29sb3IgKiBtYXRlcmlhbC5zcGVjdWxhckNvbG9yICogbm9ybSAqIExUQ19FdmFsdWF0ZSggbm9ybWFsLCB2aWV3RGlyLCBwb3NpdGlvbiwgbUludiwgcmVjdENvb3JkcyApO1xcblxcdFxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdERpZmZ1c2UgKz0gbGlnaHRDb2xvciAqIG1hdGVyaWFsLmRpZmZ1c2VDb2xvciAqIExUQ19FdmFsdWF0ZSggbm9ybWFsLCB2aWV3RGlyLCBwb3NpdGlvbiwgbWF0MyggMSApLCByZWN0Q29vcmRzICk7XFxuXFx0fVxcbiNlbmRpZlxcbnZvaWQgUkVfRGlyZWN0X0JsaW5uUGhvbmcoIGNvbnN0IGluIEluY2lkZW50TGlnaHQgZGlyZWN0TGlnaHQsIGNvbnN0IGluIEdlb21ldHJpY0NvbnRleHQgZ2VvbWV0cnksIGNvbnN0IGluIEJsaW5uUGhvbmdNYXRlcmlhbCBtYXRlcmlhbCwgaW5vdXQgUmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgKSB7XFxuXFx0I2lmZGVmIFRPT05cXG5cXHRcXHR2ZWMzIGlycmFkaWFuY2UgPSBnZXRHcmFkaWVudElycmFkaWFuY2UoIGdlb21ldHJ5Lm5vcm1hbCwgZGlyZWN0TGlnaHQuZGlyZWN0aW9uICkgKiBkaXJlY3RMaWdodC5jb2xvcjtcXG5cXHQjZWxzZVxcblxcdFxcdGZsb2F0IGRvdE5MID0gc2F0dXJhdGUoIGRvdCggZ2VvbWV0cnkubm9ybWFsLCBkaXJlY3RMaWdodC5kaXJlY3Rpb24gKSApO1xcblxcdFxcdHZlYzMgaXJyYWRpYW5jZSA9IGRvdE5MICogZGlyZWN0TGlnaHQuY29sb3I7XFxuXFx0I2VuZGlmXFxuXFx0I2lmbmRlZiBQSFlTSUNBTExZX0NPUlJFQ1RfTElHSFRTXFxuXFx0XFx0aXJyYWRpYW5jZSAqPSBQSTtcXG5cXHQjZW5kaWZcXG5cXHRyZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlICs9IGlycmFkaWFuY2UgKiBCUkRGX0RpZmZ1c2VfTGFtYmVydCggbWF0ZXJpYWwuZGlmZnVzZUNvbG9yICk7XFxuXFx0cmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIgKz0gaXJyYWRpYW5jZSAqIEJSREZfU3BlY3VsYXJfQmxpbm5QaG9uZyggZGlyZWN0TGlnaHQsIGdlb21ldHJ5LCBtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5zcGVjdWxhclNoaW5pbmVzcyApICogbWF0ZXJpYWwuc3BlY3VsYXJTdHJlbmd0aDtcXG59XFxudm9pZCBSRV9JbmRpcmVjdERpZmZ1c2VfQmxpbm5QaG9uZyggY29uc3QgaW4gdmVjMyBpcnJhZGlhbmNlLCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiBCbGlublBob25nTWF0ZXJpYWwgbWF0ZXJpYWwsIGlub3V0IFJlZmxlY3RlZExpZ2h0IHJlZmxlY3RlZExpZ2h0ICkge1xcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSArPSBpcnJhZGlhbmNlICogQlJERl9EaWZmdXNlX0xhbWJlcnQoIG1hdGVyaWFsLmRpZmZ1c2VDb2xvciApO1xcbn1cXG4jZGVmaW5lIFJFX0RpcmVjdFxcdFxcdFxcdFxcdFJFX0RpcmVjdF9CbGlublBob25nXFxuI2RlZmluZSBSRV9EaXJlY3RfUmVjdEFyZWFcXHRcXHRSRV9EaXJlY3RfUmVjdEFyZWFfQmxpbm5QaG9uZ1xcbiNkZWZpbmUgUkVfSW5kaXJlY3REaWZmdXNlXFx0XFx0UkVfSW5kaXJlY3REaWZmdXNlX0JsaW5uUGhvbmdcXG4jZGVmaW5lIE1hdGVyaWFsX0xpZ2h0UHJvYmVMT0QoIG1hdGVyaWFsIClcXHQoMClcXG5cIjtcblxudmFyIGxpZ2h0c19waHlzaWNhbF9mcmFnbWVudCA9IFwiUGh5c2ljYWxNYXRlcmlhbCBtYXRlcmlhbDtcXG5tYXRlcmlhbC5kaWZmdXNlQ29sb3IgPSBkaWZmdXNlQ29sb3IucmdiICogKCAxLjAgLSBtZXRhbG5lc3NGYWN0b3IgKTtcXG5tYXRlcmlhbC5zcGVjdWxhclJvdWdobmVzcyA9IGNsYW1wKCByb3VnaG5lc3NGYWN0b3IsIDAuMDQsIDEuMCApO1xcbiNpZmRlZiBTVEFOREFSRFxcblxcdG1hdGVyaWFsLnNwZWN1bGFyQ29sb3IgPSBtaXgoIHZlYzMoIERFRkFVTFRfU1BFQ1VMQVJfQ09FRkZJQ0lFTlQgKSwgZGlmZnVzZUNvbG9yLnJnYiwgbWV0YWxuZXNzRmFjdG9yICk7XFxuI2Vsc2VcXG5cXHRtYXRlcmlhbC5zcGVjdWxhckNvbG9yID0gbWl4KCB2ZWMzKCBNQVhJTVVNX1NQRUNVTEFSX0NPRUZGSUNJRU5UICogcG93MiggcmVmbGVjdGl2aXR5ICkgKSwgZGlmZnVzZUNvbG9yLnJnYiwgbWV0YWxuZXNzRmFjdG9yICk7XFxuXFx0bWF0ZXJpYWwuY2xlYXJDb2F0ID0gc2F0dXJhdGUoIGNsZWFyQ29hdCApO1xcdG1hdGVyaWFsLmNsZWFyQ29hdFJvdWdobmVzcyA9IGNsYW1wKCBjbGVhckNvYXRSb3VnaG5lc3MsIDAuMDQsIDEuMCApO1xcbiNlbmRpZlxcblwiO1xuXG52YXIgbGlnaHRzX3BoeXNpY2FsX3BhcnNfZnJhZ21lbnQgPSBcInN0cnVjdCBQaHlzaWNhbE1hdGVyaWFsIHtcXG5cXHR2ZWMzXFx0ZGlmZnVzZUNvbG9yO1xcblxcdGZsb2F0XFx0c3BlY3VsYXJSb3VnaG5lc3M7XFxuXFx0dmVjM1xcdHNwZWN1bGFyQ29sb3I7XFxuXFx0I2lmbmRlZiBTVEFOREFSRFxcblxcdFxcdGZsb2F0IGNsZWFyQ29hdDtcXG5cXHRcXHRmbG9hdCBjbGVhckNvYXRSb3VnaG5lc3M7XFxuXFx0I2VuZGlmXFxufTtcXG4jZGVmaW5lIE1BWElNVU1fU1BFQ1VMQVJfQ09FRkZJQ0lFTlQgMC4xNlxcbiNkZWZpbmUgREVGQVVMVF9TUEVDVUxBUl9DT0VGRklDSUVOVCAwLjA0XFxuZmxvYXQgY2xlYXJDb2F0REhSQXBwcm94KCBjb25zdCBpbiBmbG9hdCByb3VnaG5lc3MsIGNvbnN0IGluIGZsb2F0IGRvdE5MICkge1xcblxcdHJldHVybiBERUZBVUxUX1NQRUNVTEFSX0NPRUZGSUNJRU5UICsgKCAxLjAgLSBERUZBVUxUX1NQRUNVTEFSX0NPRUZGSUNJRU5UICkgKiAoIHBvdyggMS4wIC0gZG90TkwsIDUuMCApICogcG93KCAxLjAgLSByb3VnaG5lc3MsIDIuMCApICk7XFxufVxcbiNpZiBOVU1fUkVDVF9BUkVBX0xJR0hUUyA+IDBcXG5cXHR2b2lkIFJFX0RpcmVjdF9SZWN0QXJlYV9QaHlzaWNhbCggY29uc3QgaW4gUmVjdEFyZWFMaWdodCByZWN0QXJlYUxpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiBQaHlzaWNhbE1hdGVyaWFsIG1hdGVyaWFsLCBpbm91dCBSZWZsZWN0ZWRMaWdodCByZWZsZWN0ZWRMaWdodCApIHtcXG5cXHRcXHR2ZWMzIG5vcm1hbCA9IGdlb21ldHJ5Lm5vcm1hbDtcXG5cXHRcXHR2ZWMzIHZpZXdEaXIgPSBnZW9tZXRyeS52aWV3RGlyO1xcblxcdFxcdHZlYzMgcG9zaXRpb24gPSBnZW9tZXRyeS5wb3NpdGlvbjtcXG5cXHRcXHR2ZWMzIGxpZ2h0UG9zID0gcmVjdEFyZWFMaWdodC5wb3NpdGlvbjtcXG5cXHRcXHR2ZWMzIGhhbGZXaWR0aCA9IHJlY3RBcmVhTGlnaHQuaGFsZldpZHRoO1xcblxcdFxcdHZlYzMgaGFsZkhlaWdodCA9IHJlY3RBcmVhTGlnaHQuaGFsZkhlaWdodDtcXG5cXHRcXHR2ZWMzIGxpZ2h0Q29sb3IgPSByZWN0QXJlYUxpZ2h0LmNvbG9yO1xcblxcdFxcdGZsb2F0IHJvdWdobmVzcyA9IG1hdGVyaWFsLnNwZWN1bGFyUm91Z2huZXNzO1xcblxcdFxcdHZlYzMgcmVjdENvb3Jkc1sgNCBdO1xcblxcdFxcdHJlY3RDb29yZHNbIDAgXSA9IGxpZ2h0UG9zIC0gaGFsZldpZHRoIC0gaGFsZkhlaWdodDtcXHRcXHRyZWN0Q29vcmRzWyAxIF0gPSBsaWdodFBvcyArIGhhbGZXaWR0aCAtIGhhbGZIZWlnaHQ7XFxuXFx0XFx0cmVjdENvb3Jkc1sgMiBdID0gbGlnaHRQb3MgKyBoYWxmV2lkdGggKyBoYWxmSGVpZ2h0O1xcblxcdFxcdHJlY3RDb29yZHNbIDMgXSA9IGxpZ2h0UG9zIC0gaGFsZldpZHRoICsgaGFsZkhlaWdodDtcXG5cXHRcXHR2ZWMyIHV2ID0gTFRDX1V2KCBub3JtYWwsIHZpZXdEaXIsIHJvdWdobmVzcyApO1xcblxcdFxcdGZsb2F0IG5vcm0gPSB0ZXh0dXJlMkQoIGx0Y01hZywgdXYgKS5hO1xcblxcdFxcdHZlYzQgdCA9IHRleHR1cmUyRCggbHRjTWF0LCB1diApO1xcblxcdFxcdG1hdDMgbUludiA9IG1hdDMoXFxuXFx0XFx0XFx0dmVjMyggICAxLCAgIDAsIHQueSApLFxcblxcdFxcdFxcdHZlYzMoICAgMCwgdC56LCAgIDAgKSxcXG5cXHRcXHRcXHR2ZWMzKCB0LncsICAgMCwgdC54IClcXG5cXHRcXHQpO1xcblxcdFxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyICs9IGxpZ2h0Q29sb3IgKiBtYXRlcmlhbC5zcGVjdWxhckNvbG9yICogbm9ybSAqIExUQ19FdmFsdWF0ZSggbm9ybWFsLCB2aWV3RGlyLCBwb3NpdGlvbiwgbUludiwgcmVjdENvb3JkcyApO1xcblxcdFxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdERpZmZ1c2UgKz0gbGlnaHRDb2xvciAqIG1hdGVyaWFsLmRpZmZ1c2VDb2xvciAqIExUQ19FdmFsdWF0ZSggbm9ybWFsLCB2aWV3RGlyLCBwb3NpdGlvbiwgbWF0MyggMSApLCByZWN0Q29vcmRzICk7XFxuXFx0fVxcbiNlbmRpZlxcbnZvaWQgUkVfRGlyZWN0X1BoeXNpY2FsKCBjb25zdCBpbiBJbmNpZGVudExpZ2h0IGRpcmVjdExpZ2h0LCBjb25zdCBpbiBHZW9tZXRyaWNDb250ZXh0IGdlb21ldHJ5LCBjb25zdCBpbiBQaHlzaWNhbE1hdGVyaWFsIG1hdGVyaWFsLCBpbm91dCBSZWZsZWN0ZWRMaWdodCByZWZsZWN0ZWRMaWdodCApIHtcXG5cXHRmbG9hdCBkb3ROTCA9IHNhdHVyYXRlKCBkb3QoIGdlb21ldHJ5Lm5vcm1hbCwgZGlyZWN0TGlnaHQuZGlyZWN0aW9uICkgKTtcXG5cXHR2ZWMzIGlycmFkaWFuY2UgPSBkb3ROTCAqIGRpcmVjdExpZ2h0LmNvbG9yO1xcblxcdCNpZm5kZWYgUEhZU0lDQUxMWV9DT1JSRUNUX0xJR0hUU1xcblxcdFxcdGlycmFkaWFuY2UgKj0gUEk7XFxuXFx0I2VuZGlmXFxuXFx0I2lmbmRlZiBTVEFOREFSRFxcblxcdFxcdGZsb2F0IGNsZWFyQ29hdERIUiA9IG1hdGVyaWFsLmNsZWFyQ29hdCAqIGNsZWFyQ29hdERIUkFwcHJveCggbWF0ZXJpYWwuY2xlYXJDb2F0Um91Z2huZXNzLCBkb3ROTCApO1xcblxcdCNlbHNlXFxuXFx0XFx0ZmxvYXQgY2xlYXJDb2F0REhSID0gMC4wO1xcblxcdCNlbmRpZlxcblxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyICs9ICggMS4wIC0gY2xlYXJDb2F0REhSICkgKiBpcnJhZGlhbmNlICogQlJERl9TcGVjdWxhcl9HR1goIGRpcmVjdExpZ2h0LCBnZW9tZXRyeSwgbWF0ZXJpYWwuc3BlY3VsYXJDb2xvciwgbWF0ZXJpYWwuc3BlY3VsYXJSb3VnaG5lc3MgKTtcXG5cXHRyZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlICs9ICggMS4wIC0gY2xlYXJDb2F0REhSICkgKiBpcnJhZGlhbmNlICogQlJERl9EaWZmdXNlX0xhbWJlcnQoIG1hdGVyaWFsLmRpZmZ1c2VDb2xvciApO1xcblxcdCNpZm5kZWYgU1RBTkRBUkRcXG5cXHRcXHRyZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhciArPSBpcnJhZGlhbmNlICogbWF0ZXJpYWwuY2xlYXJDb2F0ICogQlJERl9TcGVjdWxhcl9HR1goIGRpcmVjdExpZ2h0LCBnZW9tZXRyeSwgdmVjMyggREVGQVVMVF9TUEVDVUxBUl9DT0VGRklDSUVOVCApLCBtYXRlcmlhbC5jbGVhckNvYXRSb3VnaG5lc3MgKTtcXG5cXHQjZW5kaWZcXG59XFxudm9pZCBSRV9JbmRpcmVjdERpZmZ1c2VfUGh5c2ljYWwoIGNvbnN0IGluIHZlYzMgaXJyYWRpYW5jZSwgY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgY29uc3QgaW4gUGh5c2ljYWxNYXRlcmlhbCBtYXRlcmlhbCwgaW5vdXQgUmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgKSB7XFxuXFx0cmVmbGVjdGVkTGlnaHQuaW5kaXJlY3REaWZmdXNlICs9IGlycmFkaWFuY2UgKiBCUkRGX0RpZmZ1c2VfTGFtYmVydCggbWF0ZXJpYWwuZGlmZnVzZUNvbG9yICk7XFxufVxcbnZvaWQgUkVfSW5kaXJlY3RTcGVjdWxhcl9QaHlzaWNhbCggY29uc3QgaW4gdmVjMyByYWRpYW5jZSwgY29uc3QgaW4gdmVjMyBjbGVhckNvYXRSYWRpYW5jZSwgY29uc3QgaW4gR2VvbWV0cmljQ29udGV4dCBnZW9tZXRyeSwgY29uc3QgaW4gUGh5c2ljYWxNYXRlcmlhbCBtYXRlcmlhbCwgaW5vdXQgUmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgKSB7XFxuXFx0I2lmbmRlZiBTVEFOREFSRFxcblxcdFxcdGZsb2F0IGRvdE5WID0gc2F0dXJhdGUoIGRvdCggZ2VvbWV0cnkubm9ybWFsLCBnZW9tZXRyeS52aWV3RGlyICkgKTtcXG5cXHRcXHRmbG9hdCBkb3ROTCA9IGRvdE5WO1xcblxcdFxcdGZsb2F0IGNsZWFyQ29hdERIUiA9IG1hdGVyaWFsLmNsZWFyQ29hdCAqIGNsZWFyQ29hdERIUkFwcHJveCggbWF0ZXJpYWwuY2xlYXJDb2F0Um91Z2huZXNzLCBkb3ROTCApO1xcblxcdCNlbHNlXFxuXFx0XFx0ZmxvYXQgY2xlYXJDb2F0REhSID0gMC4wO1xcblxcdCNlbmRpZlxcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0U3BlY3VsYXIgKz0gKCAxLjAgLSBjbGVhckNvYXRESFIgKSAqIHJhZGlhbmNlICogQlJERl9TcGVjdWxhcl9HR1hfRW52aXJvbm1lbnQoIGdlb21ldHJ5LCBtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5zcGVjdWxhclJvdWdobmVzcyApO1xcblxcdCNpZm5kZWYgU1RBTkRBUkRcXG5cXHRcXHRyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyICs9IGNsZWFyQ29hdFJhZGlhbmNlICogbWF0ZXJpYWwuY2xlYXJDb2F0ICogQlJERl9TcGVjdWxhcl9HR1hfRW52aXJvbm1lbnQoIGdlb21ldHJ5LCB2ZWMzKCBERUZBVUxUX1NQRUNVTEFSX0NPRUZGSUNJRU5UICksIG1hdGVyaWFsLmNsZWFyQ29hdFJvdWdobmVzcyApO1xcblxcdCNlbmRpZlxcbn1cXG4jZGVmaW5lIFJFX0RpcmVjdFxcdFxcdFxcdFxcdFJFX0RpcmVjdF9QaHlzaWNhbFxcbiNkZWZpbmUgUkVfRGlyZWN0X1JlY3RBcmVhXFx0XFx0UkVfRGlyZWN0X1JlY3RBcmVhX1BoeXNpY2FsXFxuI2RlZmluZSBSRV9JbmRpcmVjdERpZmZ1c2VcXHRcXHRSRV9JbmRpcmVjdERpZmZ1c2VfUGh5c2ljYWxcXG4jZGVmaW5lIFJFX0luZGlyZWN0U3BlY3VsYXJcXHRcXHRSRV9JbmRpcmVjdFNwZWN1bGFyX1BoeXNpY2FsXFxuI2RlZmluZSBNYXRlcmlhbF9CbGlublNoaW5pbmVzc0V4cG9uZW50KCBtYXRlcmlhbCApICAgR0dYUm91Z2huZXNzVG9CbGlubkV4cG9uZW50KCBtYXRlcmlhbC5zcGVjdWxhclJvdWdobmVzcyApXFxuI2RlZmluZSBNYXRlcmlhbF9DbGVhckNvYXRfQmxpbm5TaGluaW5lc3NFeHBvbmVudCggbWF0ZXJpYWwgKSAgIEdHWFJvdWdobmVzc1RvQmxpbm5FeHBvbmVudCggbWF0ZXJpYWwuY2xlYXJDb2F0Um91Z2huZXNzIClcXG5mbG9hdCBjb21wdXRlU3BlY3VsYXJPY2NsdXNpb24oIGNvbnN0IGluIGZsb2F0IGRvdE5WLCBjb25zdCBpbiBmbG9hdCBhbWJpZW50T2NjbHVzaW9uLCBjb25zdCBpbiBmbG9hdCByb3VnaG5lc3MgKSB7XFxuXFx0cmV0dXJuIHNhdHVyYXRlKCBwb3coIGRvdE5WICsgYW1iaWVudE9jY2x1c2lvbiwgZXhwMiggLSAxNi4wICogcm91Z2huZXNzIC0gMS4wICkgKSAtIDEuMCArIGFtYmllbnRPY2NsdXNpb24gKTtcXG59XFxuXCI7XG5cbnZhciBsaWdodHNfdGVtcGxhdGUgPSBcIlxcbkdlb21ldHJpY0NvbnRleHQgZ2VvbWV0cnk7XFxuZ2VvbWV0cnkucG9zaXRpb24gPSAtIHZWaWV3UG9zaXRpb247XFxuZ2VvbWV0cnkubm9ybWFsID0gbm9ybWFsO1xcbmdlb21ldHJ5LnZpZXdEaXIgPSBub3JtYWxpemUoIHZWaWV3UG9zaXRpb24gKTtcXG5JbmNpZGVudExpZ2h0IGRpcmVjdExpZ2h0O1xcbiNpZiAoIE5VTV9QT0lOVF9MSUdIVFMgPiAwICkgJiYgZGVmaW5lZCggUkVfRGlyZWN0IClcXG5cXHRQb2ludExpZ2h0IHBvaW50TGlnaHQ7XFxuXFx0Zm9yICggaW50IGkgPSAwOyBpIDwgTlVNX1BPSU5UX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHRwb2ludExpZ2h0ID0gcG9pbnRMaWdodHNbIGkgXTtcXG5cXHRcXHRnZXRQb2ludERpcmVjdExpZ2h0SXJyYWRpYW5jZSggcG9pbnRMaWdodCwgZ2VvbWV0cnksIGRpcmVjdExpZ2h0ICk7XFxuXFx0XFx0I2lmZGVmIFVTRV9TSEFET1dNQVBcXG5cXHRcXHRkaXJlY3RMaWdodC5jb2xvciAqPSBhbGwoIGJ2ZWMyKCBwb2ludExpZ2h0LnNoYWRvdywgZGlyZWN0TGlnaHQudmlzaWJsZSApICkgPyBnZXRQb2ludFNoYWRvdyggcG9pbnRTaGFkb3dNYXBbIGkgXSwgcG9pbnRMaWdodC5zaGFkb3dNYXBTaXplLCBwb2ludExpZ2h0LnNoYWRvd0JpYXMsIHBvaW50TGlnaHQuc2hhZG93UmFkaXVzLCB2UG9pbnRTaGFkb3dDb29yZFsgaSBdICkgOiAxLjA7XFxuXFx0XFx0I2VuZGlmXFxuXFx0XFx0UkVfRGlyZWN0KCBkaXJlY3RMaWdodCwgZ2VvbWV0cnksIG1hdGVyaWFsLCByZWZsZWN0ZWRMaWdodCApO1xcblxcdH1cXG4jZW5kaWZcXG4jaWYgKCBOVU1fU1BPVF9MSUdIVFMgPiAwICkgJiYgZGVmaW5lZCggUkVfRGlyZWN0IClcXG5cXHRTcG90TGlnaHQgc3BvdExpZ2h0O1xcblxcdGZvciAoIGludCBpID0gMDsgaSA8IE5VTV9TUE9UX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHRzcG90TGlnaHQgPSBzcG90TGlnaHRzWyBpIF07XFxuXFx0XFx0Z2V0U3BvdERpcmVjdExpZ2h0SXJyYWRpYW5jZSggc3BvdExpZ2h0LCBnZW9tZXRyeSwgZGlyZWN0TGlnaHQgKTtcXG5cXHRcXHQjaWZkZWYgVVNFX1NIQURPV01BUFxcblxcdFxcdGRpcmVjdExpZ2h0LmNvbG9yICo9IGFsbCggYnZlYzIoIHNwb3RMaWdodC5zaGFkb3csIGRpcmVjdExpZ2h0LnZpc2libGUgKSApID8gZ2V0U2hhZG93KCBzcG90U2hhZG93TWFwWyBpIF0sIHNwb3RMaWdodC5zaGFkb3dNYXBTaXplLCBzcG90TGlnaHQuc2hhZG93Qmlhcywgc3BvdExpZ2h0LnNoYWRvd1JhZGl1cywgdlNwb3RTaGFkb3dDb29yZFsgaSBdICkgOiAxLjA7XFxuXFx0XFx0I2VuZGlmXFxuXFx0XFx0UkVfRGlyZWN0KCBkaXJlY3RMaWdodCwgZ2VvbWV0cnksIG1hdGVyaWFsLCByZWZsZWN0ZWRMaWdodCApO1xcblxcdH1cXG4jZW5kaWZcXG4jaWYgKCBOVU1fRElSX0xJR0hUUyA+IDAgKSAmJiBkZWZpbmVkKCBSRV9EaXJlY3QgKVxcblxcdERpcmVjdGlvbmFsTGlnaHQgZGlyZWN0aW9uYWxMaWdodDtcXG5cXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fRElSX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHRkaXJlY3Rpb25hbExpZ2h0ID0gZGlyZWN0aW9uYWxMaWdodHNbIGkgXTtcXG5cXHRcXHRnZXREaXJlY3Rpb25hbERpcmVjdExpZ2h0SXJyYWRpYW5jZSggZGlyZWN0aW9uYWxMaWdodCwgZ2VvbWV0cnksIGRpcmVjdExpZ2h0ICk7XFxuXFx0XFx0I2lmZGVmIFVTRV9TSEFET1dNQVBcXG5cXHRcXHRkaXJlY3RMaWdodC5jb2xvciAqPSBhbGwoIGJ2ZWMyKCBkaXJlY3Rpb25hbExpZ2h0LnNoYWRvdywgZGlyZWN0TGlnaHQudmlzaWJsZSApICkgPyBnZXRTaGFkb3coIGRpcmVjdGlvbmFsU2hhZG93TWFwWyBpIF0sIGRpcmVjdGlvbmFsTGlnaHQuc2hhZG93TWFwU2l6ZSwgZGlyZWN0aW9uYWxMaWdodC5zaGFkb3dCaWFzLCBkaXJlY3Rpb25hbExpZ2h0LnNoYWRvd1JhZGl1cywgdkRpcmVjdGlvbmFsU2hhZG93Q29vcmRbIGkgXSApIDogMS4wO1xcblxcdFxcdCNlbmRpZlxcblxcdFxcdFJFX0RpcmVjdCggZGlyZWN0TGlnaHQsIGdlb21ldHJ5LCBtYXRlcmlhbCwgcmVmbGVjdGVkTGlnaHQgKTtcXG5cXHR9XFxuI2VuZGlmXFxuI2lmICggTlVNX1JFQ1RfQVJFQV9MSUdIVFMgPiAwICkgJiYgZGVmaW5lZCggUkVfRGlyZWN0X1JlY3RBcmVhIClcXG5cXHRSZWN0QXJlYUxpZ2h0IHJlY3RBcmVhTGlnaHQ7XFxuXFx0Zm9yICggaW50IGkgPSAwOyBpIDwgTlVNX1JFQ1RfQVJFQV9MSUdIVFM7IGkgKysgKSB7XFxuXFx0XFx0cmVjdEFyZWFMaWdodCA9IHJlY3RBcmVhTGlnaHRzWyBpIF07XFxuXFx0XFx0UkVfRGlyZWN0X1JlY3RBcmVhKCByZWN0QXJlYUxpZ2h0LCBnZW9tZXRyeSwgbWF0ZXJpYWwsIHJlZmxlY3RlZExpZ2h0ICk7XFxuXFx0fVxcbiNlbmRpZlxcbiNpZiBkZWZpbmVkKCBSRV9JbmRpcmVjdERpZmZ1c2UgKVxcblxcdHZlYzMgaXJyYWRpYW5jZSA9IGdldEFtYmllbnRMaWdodElycmFkaWFuY2UoIGFtYmllbnRMaWdodENvbG9yICk7XFxuXFx0I2lmZGVmIFVTRV9MSUdIVE1BUFxcblxcdFxcdHZlYzMgbGlnaHRNYXBJcnJhZGlhbmNlID0gdGV4dHVyZTJEKCBsaWdodE1hcCwgdlV2MiApLnh5eiAqIGxpZ2h0TWFwSW50ZW5zaXR5O1xcblxcdFxcdCNpZm5kZWYgUEhZU0lDQUxMWV9DT1JSRUNUX0xJR0hUU1xcblxcdFxcdFxcdGxpZ2h0TWFwSXJyYWRpYW5jZSAqPSBQSTtcXG5cXHRcXHQjZW5kaWZcXG5cXHRcXHRpcnJhZGlhbmNlICs9IGxpZ2h0TWFwSXJyYWRpYW5jZTtcXG5cXHQjZW5kaWZcXG5cXHQjaWYgKCBOVU1fSEVNSV9MSUdIVFMgPiAwIClcXG5cXHRcXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fSEVNSV9MSUdIVFM7IGkgKysgKSB7XFxuXFx0XFx0XFx0aXJyYWRpYW5jZSArPSBnZXRIZW1pc3BoZXJlTGlnaHRJcnJhZGlhbmNlKCBoZW1pc3BoZXJlTGlnaHRzWyBpIF0sIGdlb21ldHJ5ICk7XFxuXFx0XFx0fVxcblxcdCNlbmRpZlxcblxcdCNpZiBkZWZpbmVkKCBVU0VfRU5WTUFQICkgJiYgZGVmaW5lZCggUEhZU0lDQUwgKSAmJiBkZWZpbmVkKCBFTlZNQVBfVFlQRV9DVUJFX1VWIClcXG5cXHRcXHRpcnJhZGlhbmNlICs9IGdldExpZ2h0UHJvYmVJbmRpcmVjdElycmFkaWFuY2UoIGdlb21ldHJ5LCA4ICk7XFxuXFx0I2VuZGlmXFxuXFx0UkVfSW5kaXJlY3REaWZmdXNlKCBpcnJhZGlhbmNlLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIHJlZmxlY3RlZExpZ2h0ICk7XFxuI2VuZGlmXFxuI2lmIGRlZmluZWQoIFVTRV9FTlZNQVAgKSAmJiBkZWZpbmVkKCBSRV9JbmRpcmVjdFNwZWN1bGFyIClcXG5cXHR2ZWMzIHJhZGlhbmNlID0gZ2V0TGlnaHRQcm9iZUluZGlyZWN0UmFkaWFuY2UoIGdlb21ldHJ5LCBNYXRlcmlhbF9CbGlublNoaW5pbmVzc0V4cG9uZW50KCBtYXRlcmlhbCApLCA4ICk7XFxuXFx0I2lmbmRlZiBTVEFOREFSRFxcblxcdFxcdHZlYzMgY2xlYXJDb2F0UmFkaWFuY2UgPSBnZXRMaWdodFByb2JlSW5kaXJlY3RSYWRpYW5jZSggZ2VvbWV0cnksIE1hdGVyaWFsX0NsZWFyQ29hdF9CbGlublNoaW5pbmVzc0V4cG9uZW50KCBtYXRlcmlhbCApLCA4ICk7XFxuXFx0I2Vsc2VcXG5cXHRcXHR2ZWMzIGNsZWFyQ29hdFJhZGlhbmNlID0gdmVjMyggMC4wICk7XFxuXFx0I2VuZGlmXFxuXFx0UkVfSW5kaXJlY3RTcGVjdWxhciggcmFkaWFuY2UsIGNsZWFyQ29hdFJhZGlhbmNlLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIHJlZmxlY3RlZExpZ2h0ICk7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBsb2dkZXB0aGJ1Zl9mcmFnbWVudCA9IFwiI2lmIGRlZmluZWQoVVNFX0xPR0RFUFRIQlVGKSAmJiBkZWZpbmVkKFVTRV9MT0dERVBUSEJVRl9FWFQpXFxuXFx0Z2xfRnJhZ0RlcHRoRVhUID0gbG9nMih2RnJhZ0RlcHRoKSAqIGxvZ0RlcHRoQnVmRkMgKiAwLjU7XFxuI2VuZGlmXCI7XG5cbnZhciBsb2dkZXB0aGJ1Zl9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX0xPR0RFUFRIQlVGXFxuXFx0dW5pZm9ybSBmbG9hdCBsb2dEZXB0aEJ1ZkZDO1xcblxcdCNpZmRlZiBVU0VfTE9HREVQVEhCVUZfRVhUXFxuXFx0XFx0dmFyeWluZyBmbG9hdCB2RnJhZ0RlcHRoO1xcblxcdCNlbmRpZlxcbiNlbmRpZlxcblwiO1xuXG52YXIgbG9nZGVwdGhidWZfcGFyc192ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfTE9HREVQVEhCVUZcXG5cXHQjaWZkZWYgVVNFX0xPR0RFUFRIQlVGX0VYVFxcblxcdFxcdHZhcnlpbmcgZmxvYXQgdkZyYWdEZXB0aDtcXG5cXHQjZW5kaWZcXG5cXHR1bmlmb3JtIGZsb2F0IGxvZ0RlcHRoQnVmRkM7XFxuI2VuZGlmXCI7XG5cbnZhciBsb2dkZXB0aGJ1Zl92ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfTE9HREVQVEhCVUZcXG5cXHRnbF9Qb3NpdGlvbi56ID0gbG9nMihtYXgoIEVQU0lMT04sIGdsX1Bvc2l0aW9uLncgKyAxLjAgKSkgKiBsb2dEZXB0aEJ1ZkZDO1xcblxcdCNpZmRlZiBVU0VfTE9HREVQVEhCVUZfRVhUXFxuXFx0XFx0dkZyYWdEZXB0aCA9IDEuMCArIGdsX1Bvc2l0aW9uLnc7XFxuXFx0I2Vsc2VcXG5cXHRcXHRnbF9Qb3NpdGlvbi56ID0gKGdsX1Bvc2l0aW9uLnogLSAxLjApICogZ2xfUG9zaXRpb24udztcXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIG1hcF9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9NQVBcXG5cXHR2ZWM0IHRleGVsQ29sb3IgPSB0ZXh0dXJlMkQoIG1hcCwgdlV2ICk7XFxuXFx0dGV4ZWxDb2xvciA9IG1hcFRleGVsVG9MaW5lYXIoIHRleGVsQ29sb3IgKTtcXG5cXHRkaWZmdXNlQ29sb3IgKj0gdGV4ZWxDb2xvcjtcXG4jZW5kaWZcXG5cIjtcblxudmFyIG1hcF9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX01BUFxcblxcdHVuaWZvcm0gc2FtcGxlcjJEIG1hcDtcXG4jZW5kaWZcXG5cIjtcblxudmFyIG1hcF9wYXJ0aWNsZV9mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9NQVBcXG5cXHR2ZWM0IG1hcFRleGVsID0gdGV4dHVyZTJEKCBtYXAsIHZlYzIoIGdsX1BvaW50Q29vcmQueCwgMS4wIC0gZ2xfUG9pbnRDb29yZC55ICkgKiBvZmZzZXRSZXBlYXQuencgKyBvZmZzZXRSZXBlYXQueHkgKTtcXG5cXHRkaWZmdXNlQ29sb3IgKj0gbWFwVGV4ZWxUb0xpbmVhciggbWFwVGV4ZWwgKTtcXG4jZW5kaWZcXG5cIjtcblxudmFyIG1hcF9wYXJ0aWNsZV9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX01BUFxcblxcdHVuaWZvcm0gdmVjNCBvZmZzZXRSZXBlYXQ7XFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgbWFwO1xcbiNlbmRpZlxcblwiO1xuXG52YXIgbWV0YWxuZXNzbWFwX2ZyYWdtZW50ID0gXCJmbG9hdCBtZXRhbG5lc3NGYWN0b3IgPSBtZXRhbG5lc3M7XFxuI2lmZGVmIFVTRV9NRVRBTE5FU1NNQVBcXG5cXHR2ZWM0IHRleGVsTWV0YWxuZXNzID0gdGV4dHVyZTJEKCBtZXRhbG5lc3NNYXAsIHZVdiApO1xcblxcdG1ldGFsbmVzc0ZhY3RvciAqPSB0ZXhlbE1ldGFsbmVzcy5iO1xcbiNlbmRpZlxcblwiO1xuXG52YXIgbWV0YWxuZXNzbWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfTUVUQUxORVNTTUFQXFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgbWV0YWxuZXNzTWFwO1xcbiNlbmRpZlwiO1xuXG52YXIgbW9ycGhub3JtYWxfdmVydGV4ID0gXCIjaWZkZWYgVVNFX01PUlBITk9STUFMU1xcblxcdG9iamVjdE5vcm1hbCArPSAoIG1vcnBoTm9ybWFsMCAtIG5vcm1hbCApICogbW9ycGhUYXJnZXRJbmZsdWVuY2VzWyAwIF07XFxuXFx0b2JqZWN0Tm9ybWFsICs9ICggbW9ycGhOb3JtYWwxIC0gbm9ybWFsICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDEgXTtcXG5cXHRvYmplY3ROb3JtYWwgKz0gKCBtb3JwaE5vcm1hbDIgLSBub3JtYWwgKSAqIG1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMiBdO1xcblxcdG9iamVjdE5vcm1hbCArPSAoIG1vcnBoTm9ybWFsMyAtIG5vcm1hbCApICogbW9ycGhUYXJnZXRJbmZsdWVuY2VzWyAzIF07XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBtb3JwaHRhcmdldF9wYXJzX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9NT1JQSFRBUkdFVFNcXG5cXHQjaWZuZGVmIFVTRV9NT1JQSE5PUk1BTFNcXG5cXHR1bmlmb3JtIGZsb2F0IG1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgOCBdO1xcblxcdCNlbHNlXFxuXFx0dW5pZm9ybSBmbG9hdCBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDQgXTtcXG5cXHQjZW5kaWZcXG4jZW5kaWZcIjtcblxudmFyIG1vcnBodGFyZ2V0X3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9NT1JQSFRBUkdFVFNcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0MCAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDAgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0MSAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDEgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0MiAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDIgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0MyAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDMgXTtcXG5cXHQjaWZuZGVmIFVTRV9NT1JQSE5PUk1BTFNcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0NCAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDQgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0NSAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDUgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0NiAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDYgXTtcXG5cXHR0cmFuc2Zvcm1lZCArPSAoIG1vcnBoVGFyZ2V0NyAtIHBvc2l0aW9uICkgKiBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIDcgXTtcXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIG5vcm1hbF9mbGlwID0gXCIjaWZkZWYgRE9VQkxFX1NJREVEXFxuXFx0ZmxvYXQgZmxpcE5vcm1hbCA9ICggZmxvYXQoIGdsX0Zyb250RmFjaW5nICkgKiAyLjAgLSAxLjAgKTtcXG4jZWxzZVxcblxcdGZsb2F0IGZsaXBOb3JtYWwgPSAxLjA7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBub3JtYWxfZnJhZ21lbnQgPSBcIiNpZmRlZiBGTEFUX1NIQURFRFxcblxcdHZlYzMgZmR4ID0gdmVjMyggZEZkeCggdlZpZXdQb3NpdGlvbi54ICksIGRGZHgoIHZWaWV3UG9zaXRpb24ueSApLCBkRmR4KCB2Vmlld1Bvc2l0aW9uLnogKSApO1xcblxcdHZlYzMgZmR5ID0gdmVjMyggZEZkeSggdlZpZXdQb3NpdGlvbi54ICksIGRGZHkoIHZWaWV3UG9zaXRpb24ueSApLCBkRmR5KCB2Vmlld1Bvc2l0aW9uLnogKSApO1xcblxcdHZlYzMgbm9ybWFsID0gbm9ybWFsaXplKCBjcm9zcyggZmR4LCBmZHkgKSApO1xcbiNlbHNlXFxuXFx0dmVjMyBub3JtYWwgPSBub3JtYWxpemUoIHZOb3JtYWwgKSAqIGZsaXBOb3JtYWw7XFxuI2VuZGlmXFxuI2lmZGVmIFVTRV9OT1JNQUxNQVBcXG5cXHRub3JtYWwgPSBwZXJ0dXJiTm9ybWFsMkFyYiggLXZWaWV3UG9zaXRpb24sIG5vcm1hbCApO1xcbiNlbGlmIGRlZmluZWQoIFVTRV9CVU1QTUFQIClcXG5cXHRub3JtYWwgPSBwZXJ0dXJiTm9ybWFsQXJiKCAtdlZpZXdQb3NpdGlvbiwgbm9ybWFsLCBkSGR4eV9md2QoKSApO1xcbiNlbmRpZlxcblwiO1xuXG52YXIgbm9ybWFsbWFwX3BhcnNfZnJhZ21lbnQgPSBcIiNpZmRlZiBVU0VfTk9STUFMTUFQXFxuXFx0dW5pZm9ybSBzYW1wbGVyMkQgbm9ybWFsTWFwO1xcblxcdHVuaWZvcm0gdmVjMiBub3JtYWxTY2FsZTtcXG5cXHR2ZWMzIHBlcnR1cmJOb3JtYWwyQXJiKCB2ZWMzIGV5ZV9wb3MsIHZlYzMgc3VyZl9ub3JtICkge1xcblxcdFxcdHZlYzMgcTAgPSBkRmR4KCBleWVfcG9zLnh5eiApO1xcblxcdFxcdHZlYzMgcTEgPSBkRmR5KCBleWVfcG9zLnh5eiApO1xcblxcdFxcdHZlYzIgc3QwID0gZEZkeCggdlV2LnN0ICk7XFxuXFx0XFx0dmVjMiBzdDEgPSBkRmR5KCB2VXYuc3QgKTtcXG5cXHRcXHR2ZWMzIFMgPSBub3JtYWxpemUoIHEwICogc3QxLnQgLSBxMSAqIHN0MC50ICk7XFxuXFx0XFx0dmVjMyBUID0gbm9ybWFsaXplKCAtcTAgKiBzdDEucyArIHExICogc3QwLnMgKTtcXG5cXHRcXHR2ZWMzIE4gPSBub3JtYWxpemUoIHN1cmZfbm9ybSApO1xcblxcdFxcdHZlYzMgbWFwTiA9IHRleHR1cmUyRCggbm9ybWFsTWFwLCB2VXYgKS54eXogKiAyLjAgLSAxLjA7XFxuXFx0XFx0bWFwTi54eSA9IG5vcm1hbFNjYWxlICogbWFwTi54eTtcXG5cXHRcXHRtYXQzIHRzbiA9IG1hdDMoIFMsIFQsIE4gKTtcXG5cXHRcXHRyZXR1cm4gbm9ybWFsaXplKCB0c24gKiBtYXBOICk7XFxuXFx0fVxcbiNlbmRpZlxcblwiO1xuXG52YXIgcGFja2luZyA9IFwidmVjMyBwYWNrTm9ybWFsVG9SR0IoIGNvbnN0IGluIHZlYzMgbm9ybWFsICkge1xcblxcdHJldHVybiBub3JtYWxpemUoIG5vcm1hbCApICogMC41ICsgMC41O1xcbn1cXG52ZWMzIHVucGFja1JHQlRvTm9ybWFsKCBjb25zdCBpbiB2ZWMzIHJnYiApIHtcXG5cXHRyZXR1cm4gMS4wIC0gMi4wICogcmdiLnh5ejtcXG59XFxuY29uc3QgZmxvYXQgUGFja1Vwc2NhbGUgPSAyNTYuIC8gMjU1Ljtjb25zdCBmbG9hdCBVbnBhY2tEb3duc2NhbGUgPSAyNTUuIC8gMjU2LjtcXG5jb25zdCB2ZWMzIFBhY2tGYWN0b3JzID0gdmVjMyggMjU2LiAqIDI1Ni4gKiAyNTYuLCAyNTYuICogMjU2LiwgIDI1Ni4gKTtcXG5jb25zdCB2ZWM0IFVucGFja0ZhY3RvcnMgPSBVbnBhY2tEb3duc2NhbGUgLyB2ZWM0KCBQYWNrRmFjdG9ycywgMS4gKTtcXG5jb25zdCBmbG9hdCBTaGlmdFJpZ2h0OCA9IDEuIC8gMjU2LjtcXG52ZWM0IHBhY2tEZXB0aFRvUkdCQSggY29uc3QgaW4gZmxvYXQgdiApIHtcXG5cXHR2ZWM0IHIgPSB2ZWM0KCBmcmFjdCggdiAqIFBhY2tGYWN0b3JzICksIHYgKTtcXG5cXHRyLnl6dyAtPSByLnh5eiAqIFNoaWZ0UmlnaHQ4O1xcdHJldHVybiByICogUGFja1Vwc2NhbGU7XFxufVxcbmZsb2F0IHVucGFja1JHQkFUb0RlcHRoKCBjb25zdCBpbiB2ZWM0IHYgKSB7XFxuXFx0cmV0dXJuIGRvdCggdiwgVW5wYWNrRmFjdG9ycyApO1xcbn1cXG5mbG9hdCB2aWV3WlRvT3J0aG9ncmFwaGljRGVwdGgoIGNvbnN0IGluIGZsb2F0IHZpZXdaLCBjb25zdCBpbiBmbG9hdCBuZWFyLCBjb25zdCBpbiBmbG9hdCBmYXIgKSB7XFxuXFx0cmV0dXJuICggdmlld1ogKyBuZWFyICkgLyAoIG5lYXIgLSBmYXIgKTtcXG59XFxuZmxvYXQgb3J0aG9ncmFwaGljRGVwdGhUb1ZpZXdaKCBjb25zdCBpbiBmbG9hdCBsaW5lYXJDbGlwWiwgY29uc3QgaW4gZmxvYXQgbmVhciwgY29uc3QgaW4gZmxvYXQgZmFyICkge1xcblxcdHJldHVybiBsaW5lYXJDbGlwWiAqICggbmVhciAtIGZhciApIC0gbmVhcjtcXG59XFxuZmxvYXQgdmlld1pUb1BlcnNwZWN0aXZlRGVwdGgoIGNvbnN0IGluIGZsb2F0IHZpZXdaLCBjb25zdCBpbiBmbG9hdCBuZWFyLCBjb25zdCBpbiBmbG9hdCBmYXIgKSB7XFxuXFx0cmV0dXJuICgoIG5lYXIgKyB2aWV3WiApICogZmFyICkgLyAoKCBmYXIgLSBuZWFyICkgKiB2aWV3WiApO1xcbn1cXG5mbG9hdCBwZXJzcGVjdGl2ZURlcHRoVG9WaWV3WiggY29uc3QgaW4gZmxvYXQgaW52Q2xpcFosIGNvbnN0IGluIGZsb2F0IG5lYXIsIGNvbnN0IGluIGZsb2F0IGZhciApIHtcXG5cXHRyZXR1cm4gKCBuZWFyICogZmFyICkgLyAoICggZmFyIC0gbmVhciApICogaW52Q2xpcFogLSBmYXIgKTtcXG59XFxuXCI7XG5cbnZhciBwcmVtdWx0aXBsaWVkX2FscGhhX2ZyYWdtZW50ID0gXCIjaWZkZWYgUFJFTVVMVElQTElFRF9BTFBIQVxcblxcdGdsX0ZyYWdDb2xvci5yZ2IgKj0gZ2xfRnJhZ0NvbG9yLmE7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBwcm9qZWN0X3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9TS0lOTklOR1xcblxcdHZlYzQgbXZQb3NpdGlvbiA9IG1vZGVsVmlld01hdHJpeCAqIHNraW5uZWQ7XFxuI2Vsc2VcXG5cXHR2ZWM0IG12UG9zaXRpb24gPSBtb2RlbFZpZXdNYXRyaXggKiB2ZWM0KCB0cmFuc2Zvcm1lZCwgMS4wICk7XFxuI2VuZGlmXFxuZ2xfUG9zaXRpb24gPSBwcm9qZWN0aW9uTWF0cml4ICogbXZQb3NpdGlvbjtcXG5cIjtcblxudmFyIGRpdGhlcmluZ19mcmFnbWVudCA9IFwiI2lmIGRlZmluZWQoIERJVEhFUklORyApXFxuICBnbF9GcmFnQ29sb3IucmdiID0gZGl0aGVyaW5nKCBnbF9GcmFnQ29sb3IucmdiICk7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBkaXRoZXJpbmdfcGFyc19mcmFnbWVudCA9IFwiI2lmIGRlZmluZWQoIERJVEhFUklORyApXFxuXFx0dmVjMyBkaXRoZXJpbmcoIHZlYzMgY29sb3IgKSB7XFxuXFx0XFx0ZmxvYXQgZ3JpZF9wb3NpdGlvbiA9IHJhbmQoIGdsX0ZyYWdDb29yZC54eSApO1xcblxcdFxcdHZlYzMgZGl0aGVyX3NoaWZ0X1JHQiA9IHZlYzMoIDAuMjUgLyAyNTUuMCwgLTAuMjUgLyAyNTUuMCwgMC4yNSAvIDI1NS4wICk7XFxuXFx0XFx0ZGl0aGVyX3NoaWZ0X1JHQiA9IG1peCggMi4wICogZGl0aGVyX3NoaWZ0X1JHQiwgLTIuMCAqIGRpdGhlcl9zaGlmdF9SR0IsIGdyaWRfcG9zaXRpb24gKTtcXG5cXHRcXHRyZXR1cm4gY29sb3IgKyBkaXRoZXJfc2hpZnRfUkdCO1xcblxcdH1cXG4jZW5kaWZcXG5cIjtcblxudmFyIHJvdWdobmVzc21hcF9mcmFnbWVudCA9IFwiZmxvYXQgcm91Z2huZXNzRmFjdG9yID0gcm91Z2huZXNzO1xcbiNpZmRlZiBVU0VfUk9VR0hORVNTTUFQXFxuXFx0dmVjNCB0ZXhlbFJvdWdobmVzcyA9IHRleHR1cmUyRCggcm91Z2huZXNzTWFwLCB2VXYgKTtcXG5cXHRyb3VnaG5lc3NGYWN0b3IgKj0gdGV4ZWxSb3VnaG5lc3MuZztcXG4jZW5kaWZcXG5cIjtcblxudmFyIHJvdWdobmVzc21hcF9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX1JPVUdITkVTU01BUFxcblxcdHVuaWZvcm0gc2FtcGxlcjJEIHJvdWdobmVzc01hcDtcXG4jZW5kaWZcIjtcblxudmFyIHNoYWRvd21hcF9wYXJzX2ZyYWdtZW50ID0gXCIjaWZkZWYgVVNFX1NIQURPV01BUFxcblxcdCNpZiBOVU1fRElSX0xJR0hUUyA+IDBcXG5cXHRcXHR1bmlmb3JtIHNhbXBsZXIyRCBkaXJlY3Rpb25hbFNoYWRvd01hcFsgTlVNX0RJUl9MSUdIVFMgXTtcXG5cXHRcXHR2YXJ5aW5nIHZlYzQgdkRpcmVjdGlvbmFsU2hhZG93Q29vcmRbIE5VTV9ESVJfTElHSFRTIF07XFxuXFx0I2VuZGlmXFxuXFx0I2lmIE5VTV9TUE9UX0xJR0hUUyA+IDBcXG5cXHRcXHR1bmlmb3JtIHNhbXBsZXIyRCBzcG90U2hhZG93TWFwWyBOVU1fU1BPVF9MSUdIVFMgXTtcXG5cXHRcXHR2YXJ5aW5nIHZlYzQgdlNwb3RTaGFkb3dDb29yZFsgTlVNX1NQT1RfTElHSFRTIF07XFxuXFx0I2VuZGlmXFxuXFx0I2lmIE5VTV9QT0lOVF9MSUdIVFMgPiAwXFxuXFx0XFx0dW5pZm9ybSBzYW1wbGVyMkQgcG9pbnRTaGFkb3dNYXBbIE5VTV9QT0lOVF9MSUdIVFMgXTtcXG5cXHRcXHR2YXJ5aW5nIHZlYzQgdlBvaW50U2hhZG93Q29vcmRbIE5VTV9QT0lOVF9MSUdIVFMgXTtcXG5cXHQjZW5kaWZcXG5cXHRmbG9hdCB0ZXh0dXJlMkRDb21wYXJlKCBzYW1wbGVyMkQgZGVwdGhzLCB2ZWMyIHV2LCBmbG9hdCBjb21wYXJlICkge1xcblxcdFxcdHJldHVybiBzdGVwKCBjb21wYXJlLCB1bnBhY2tSR0JBVG9EZXB0aCggdGV4dHVyZTJEKCBkZXB0aHMsIHV2ICkgKSApO1xcblxcdH1cXG5cXHRmbG9hdCB0ZXh0dXJlMkRTaGFkb3dMZXJwKCBzYW1wbGVyMkQgZGVwdGhzLCB2ZWMyIHNpemUsIHZlYzIgdXYsIGZsb2F0IGNvbXBhcmUgKSB7XFxuXFx0XFx0Y29uc3QgdmVjMiBvZmZzZXQgPSB2ZWMyKCAwLjAsIDEuMCApO1xcblxcdFxcdHZlYzIgdGV4ZWxTaXplID0gdmVjMiggMS4wICkgLyBzaXplO1xcblxcdFxcdHZlYzIgY2VudHJvaWRVViA9IGZsb29yKCB1diAqIHNpemUgKyAwLjUgKSAvIHNpemU7XFxuXFx0XFx0ZmxvYXQgbGIgPSB0ZXh0dXJlMkRDb21wYXJlKCBkZXB0aHMsIGNlbnRyb2lkVVYgKyB0ZXhlbFNpemUgKiBvZmZzZXQueHgsIGNvbXBhcmUgKTtcXG5cXHRcXHRmbG9hdCBsdCA9IHRleHR1cmUyRENvbXBhcmUoIGRlcHRocywgY2VudHJvaWRVViArIHRleGVsU2l6ZSAqIG9mZnNldC54eSwgY29tcGFyZSApO1xcblxcdFxcdGZsb2F0IHJiID0gdGV4dHVyZTJEQ29tcGFyZSggZGVwdGhzLCBjZW50cm9pZFVWICsgdGV4ZWxTaXplICogb2Zmc2V0Lnl4LCBjb21wYXJlICk7XFxuXFx0XFx0ZmxvYXQgcnQgPSB0ZXh0dXJlMkRDb21wYXJlKCBkZXB0aHMsIGNlbnRyb2lkVVYgKyB0ZXhlbFNpemUgKiBvZmZzZXQueXksIGNvbXBhcmUgKTtcXG5cXHRcXHR2ZWMyIGYgPSBmcmFjdCggdXYgKiBzaXplICsgMC41ICk7XFxuXFx0XFx0ZmxvYXQgYSA9IG1peCggbGIsIGx0LCBmLnkgKTtcXG5cXHRcXHRmbG9hdCBiID0gbWl4KCByYiwgcnQsIGYueSApO1xcblxcdFxcdGZsb2F0IGMgPSBtaXgoIGEsIGIsIGYueCApO1xcblxcdFxcdHJldHVybiBjO1xcblxcdH1cXG5cXHRmbG9hdCBnZXRTaGFkb3coIHNhbXBsZXIyRCBzaGFkb3dNYXAsIHZlYzIgc2hhZG93TWFwU2l6ZSwgZmxvYXQgc2hhZG93QmlhcywgZmxvYXQgc2hhZG93UmFkaXVzLCB2ZWM0IHNoYWRvd0Nvb3JkICkge1xcblxcdFxcdHNoYWRvd0Nvb3JkLnh5eiAvPSBzaGFkb3dDb29yZC53O1xcblxcdFxcdHNoYWRvd0Nvb3JkLnogKz0gc2hhZG93QmlhcztcXG5cXHRcXHRidmVjNCBpbkZydXN0dW1WZWMgPSBidmVjNCAoIHNoYWRvd0Nvb3JkLnggPj0gMC4wLCBzaGFkb3dDb29yZC54IDw9IDEuMCwgc2hhZG93Q29vcmQueSA+PSAwLjAsIHNoYWRvd0Nvb3JkLnkgPD0gMS4wICk7XFxuXFx0XFx0Ym9vbCBpbkZydXN0dW0gPSBhbGwoIGluRnJ1c3R1bVZlYyApO1xcblxcdFxcdGJ2ZWMyIGZydXN0dW1UZXN0VmVjID0gYnZlYzIoIGluRnJ1c3R1bSwgc2hhZG93Q29vcmQueiA8PSAxLjAgKTtcXG5cXHRcXHRib29sIGZydXN0dW1UZXN0ID0gYWxsKCBmcnVzdHVtVGVzdFZlYyApO1xcblxcdFxcdGlmICggZnJ1c3R1bVRlc3QgKSB7XFxuXFx0XFx0I2lmIGRlZmluZWQoIFNIQURPV01BUF9UWVBFX1BDRiApXFxuXFx0XFx0XFx0dmVjMiB0ZXhlbFNpemUgPSB2ZWMyKCAxLjAgKSAvIHNoYWRvd01hcFNpemU7XFxuXFx0XFx0XFx0ZmxvYXQgZHgwID0gLSB0ZXhlbFNpemUueCAqIHNoYWRvd1JhZGl1cztcXG5cXHRcXHRcXHRmbG9hdCBkeTAgPSAtIHRleGVsU2l6ZS55ICogc2hhZG93UmFkaXVzO1xcblxcdFxcdFxcdGZsb2F0IGR4MSA9ICsgdGV4ZWxTaXplLnggKiBzaGFkb3dSYWRpdXM7XFxuXFx0XFx0XFx0ZmxvYXQgZHkxID0gKyB0ZXhlbFNpemUueSAqIHNoYWRvd1JhZGl1cztcXG5cXHRcXHRcXHRyZXR1cm4gKFxcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgc2hhZG93Q29vcmQueHkgKyB2ZWMyKCBkeDAsIGR5MCApLCBzaGFkb3dDb29yZC56ICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgc2hhZG93Q29vcmQueHkgKyB2ZWMyKCAwLjAsIGR5MCApLCBzaGFkb3dDb29yZC56ICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgc2hhZG93Q29vcmQueHkgKyB2ZWMyKCBkeDEsIGR5MCApLCBzaGFkb3dDb29yZC56ICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgc2hhZG93Q29vcmQueHkgKyB2ZWMyKCBkeDAsIDAuMCApLCBzaGFkb3dDb29yZC56ICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgc2hhZG93Q29vcmQueHksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MSwgMC4wICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MCwgZHkxICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIDAuMCwgZHkxICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MSwgZHkxICksIHNoYWRvd0Nvb3JkLnogKVxcblxcdFxcdFxcdCkgKiAoIDEuMCAvIDkuMCApO1xcblxcdFxcdCNlbGlmIGRlZmluZWQoIFNIQURPV01BUF9UWVBFX1BDRl9TT0ZUIClcXG5cXHRcXHRcXHR2ZWMyIHRleGVsU2l6ZSA9IHZlYzIoIDEuMCApIC8gc2hhZG93TWFwU2l6ZTtcXG5cXHRcXHRcXHRmbG9hdCBkeDAgPSAtIHRleGVsU2l6ZS54ICogc2hhZG93UmFkaXVzO1xcblxcdFxcdFxcdGZsb2F0IGR5MCA9IC0gdGV4ZWxTaXplLnkgKiBzaGFkb3dSYWRpdXM7XFxuXFx0XFx0XFx0ZmxvYXQgZHgxID0gKyB0ZXhlbFNpemUueCAqIHNoYWRvd1JhZGl1cztcXG5cXHRcXHRcXHRmbG9hdCBkeTEgPSArIHRleGVsU2l6ZS55ICogc2hhZG93UmFkaXVzO1xcblxcdFxcdFxcdHJldHVybiAoXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEU2hhZG93TGVycCggc2hhZG93TWFwLCBzaGFkb3dNYXBTaXplLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MCwgZHkwICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEU2hhZG93TGVycCggc2hhZG93TWFwLCBzaGFkb3dNYXBTaXplLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIDAuMCwgZHkwICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEU2hhZG93TGVycCggc2hhZG93TWFwLCBzaGFkb3dNYXBTaXplLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MSwgZHkwICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEU2hhZG93TGVycCggc2hhZG93TWFwLCBzaGFkb3dNYXBTaXplLCBzaGFkb3dDb29yZC54eSArIHZlYzIoIGR4MCwgMC4wICksIHNoYWRvd0Nvb3JkLnogKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEU2hhZG93TGVycCggc2hhZG93TWFwLCBzaGFkb3dNYXBTaXplLCBzaGFkb3dDb29yZC54eSwgc2hhZG93Q29vcmQueiApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRTaGFkb3dMZXJwKCBzaGFkb3dNYXAsIHNoYWRvd01hcFNpemUsIHNoYWRvd0Nvb3JkLnh5ICsgdmVjMiggZHgxLCAwLjAgKSwgc2hhZG93Q29vcmQueiApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRTaGFkb3dMZXJwKCBzaGFkb3dNYXAsIHNoYWRvd01hcFNpemUsIHNoYWRvd0Nvb3JkLnh5ICsgdmVjMiggZHgwLCBkeTEgKSwgc2hhZG93Q29vcmQueiApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRTaGFkb3dMZXJwKCBzaGFkb3dNYXAsIHNoYWRvd01hcFNpemUsIHNoYWRvd0Nvb3JkLnh5ICsgdmVjMiggMC4wLCBkeTEgKSwgc2hhZG93Q29vcmQueiApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRTaGFkb3dMZXJwKCBzaGFkb3dNYXAsIHNoYWRvd01hcFNpemUsIHNoYWRvd0Nvb3JkLnh5ICsgdmVjMiggZHgxLCBkeTEgKSwgc2hhZG93Q29vcmQueiApXFxuXFx0XFx0XFx0KSAqICggMS4wIC8gOS4wICk7XFxuXFx0XFx0I2Vsc2VcXG5cXHRcXHRcXHRyZXR1cm4gdGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBzaGFkb3dDb29yZC54eSwgc2hhZG93Q29vcmQueiApO1xcblxcdFxcdCNlbmRpZlxcblxcdFxcdH1cXG5cXHRcXHRyZXR1cm4gMS4wO1xcblxcdH1cXG5cXHR2ZWMyIGN1YmVUb1VWKCB2ZWMzIHYsIGZsb2F0IHRleGVsU2l6ZVkgKSB7XFxuXFx0XFx0dmVjMyBhYnNWID0gYWJzKCB2ICk7XFxuXFx0XFx0ZmxvYXQgc2NhbGVUb0N1YmUgPSAxLjAgLyBtYXgoIGFic1YueCwgbWF4KCBhYnNWLnksIGFic1YueiApICk7XFxuXFx0XFx0YWJzViAqPSBzY2FsZVRvQ3ViZTtcXG5cXHRcXHR2ICo9IHNjYWxlVG9DdWJlICogKCAxLjAgLSAyLjAgKiB0ZXhlbFNpemVZICk7XFxuXFx0XFx0dmVjMiBwbGFuYXIgPSB2Lnh5O1xcblxcdFxcdGZsb2F0IGFsbW9zdEFUZXhlbCA9IDEuNSAqIHRleGVsU2l6ZVk7XFxuXFx0XFx0ZmxvYXQgYWxtb3N0T25lID0gMS4wIC0gYWxtb3N0QVRleGVsO1xcblxcdFxcdGlmICggYWJzVi56ID49IGFsbW9zdE9uZSApIHtcXG5cXHRcXHRcXHRpZiAoIHYueiA+IDAuMCApXFxuXFx0XFx0XFx0XFx0cGxhbmFyLnggPSA0LjAgLSB2Lng7XFxuXFx0XFx0fSBlbHNlIGlmICggYWJzVi54ID49IGFsbW9zdE9uZSApIHtcXG5cXHRcXHRcXHRmbG9hdCBzaWduWCA9IHNpZ24oIHYueCApO1xcblxcdFxcdFxcdHBsYW5hci54ID0gdi56ICogc2lnblggKyAyLjAgKiBzaWduWDtcXG5cXHRcXHR9IGVsc2UgaWYgKCBhYnNWLnkgPj0gYWxtb3N0T25lICkge1xcblxcdFxcdFxcdGZsb2F0IHNpZ25ZID0gc2lnbiggdi55ICk7XFxuXFx0XFx0XFx0cGxhbmFyLnggPSB2LnggKyAyLjAgKiBzaWduWSArIDIuMDtcXG5cXHRcXHRcXHRwbGFuYXIueSA9IHYueiAqIHNpZ25ZIC0gMi4wO1xcblxcdFxcdH1cXG5cXHRcXHRyZXR1cm4gdmVjMiggMC4xMjUsIDAuMjUgKSAqIHBsYW5hciArIHZlYzIoIDAuMzc1LCAwLjc1ICk7XFxuXFx0fVxcblxcdGZsb2F0IGdldFBvaW50U2hhZG93KCBzYW1wbGVyMkQgc2hhZG93TWFwLCB2ZWMyIHNoYWRvd01hcFNpemUsIGZsb2F0IHNoYWRvd0JpYXMsIGZsb2F0IHNoYWRvd1JhZGl1cywgdmVjNCBzaGFkb3dDb29yZCApIHtcXG5cXHRcXHR2ZWMyIHRleGVsU2l6ZSA9IHZlYzIoIDEuMCApIC8gKCBzaGFkb3dNYXBTaXplICogdmVjMiggNC4wLCAyLjAgKSApO1xcblxcdFxcdHZlYzMgbGlnaHRUb1Bvc2l0aW9uID0gc2hhZG93Q29vcmQueHl6O1xcblxcdFxcdHZlYzMgYmQzRCA9IG5vcm1hbGl6ZSggbGlnaHRUb1Bvc2l0aW9uICk7XFxuXFx0XFx0ZmxvYXQgZHAgPSAoIGxlbmd0aCggbGlnaHRUb1Bvc2l0aW9uICkgLSBzaGFkb3dCaWFzICkgLyAxMDAwLjA7XFxuXFx0XFx0I2lmIGRlZmluZWQoIFNIQURPV01BUF9UWVBFX1BDRiApIHx8IGRlZmluZWQoIFNIQURPV01BUF9UWVBFX1BDRl9TT0ZUIClcXG5cXHRcXHRcXHR2ZWMyIG9mZnNldCA9IHZlYzIoIC0gMSwgMSApICogc2hhZG93UmFkaXVzICogdGV4ZWxTaXplLnk7XFxuXFx0XFx0XFx0cmV0dXJuIChcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRDb21wYXJlKCBzaGFkb3dNYXAsIGN1YmVUb1VWKCBiZDNEICsgb2Zmc2V0Lnh5eSwgdGV4ZWxTaXplLnkgKSwgZHAgKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBjdWJlVG9VViggYmQzRCArIG9mZnNldC55eXksIHRleGVsU2l6ZS55ICksIGRwICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgY3ViZVRvVVYoIGJkM0QgKyBvZmZzZXQueHl4LCB0ZXhlbFNpemUueSApLCBkcCApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRDb21wYXJlKCBzaGFkb3dNYXAsIGN1YmVUb1VWKCBiZDNEICsgb2Zmc2V0Lnl5eCwgdGV4ZWxTaXplLnkgKSwgZHAgKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBjdWJlVG9VViggYmQzRCwgdGV4ZWxTaXplLnkgKSwgZHAgKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBjdWJlVG9VViggYmQzRCArIG9mZnNldC54eHksIHRleGVsU2l6ZS55ICksIGRwICkgK1xcblxcdFxcdFxcdFxcdHRleHR1cmUyRENvbXBhcmUoIHNoYWRvd01hcCwgY3ViZVRvVVYoIGJkM0QgKyBvZmZzZXQueXh5LCB0ZXhlbFNpemUueSApLCBkcCApICtcXG5cXHRcXHRcXHRcXHR0ZXh0dXJlMkRDb21wYXJlKCBzaGFkb3dNYXAsIGN1YmVUb1VWKCBiZDNEICsgb2Zmc2V0Lnh4eCwgdGV4ZWxTaXplLnkgKSwgZHAgKSArXFxuXFx0XFx0XFx0XFx0dGV4dHVyZTJEQ29tcGFyZSggc2hhZG93TWFwLCBjdWJlVG9VViggYmQzRCArIG9mZnNldC55eHgsIHRleGVsU2l6ZS55ICksIGRwIClcXG5cXHRcXHRcXHQpICogKCAxLjAgLyA5LjAgKTtcXG5cXHRcXHQjZWxzZVxcblxcdFxcdFxcdHJldHVybiB0ZXh0dXJlMkRDb21wYXJlKCBzaGFkb3dNYXAsIGN1YmVUb1VWKCBiZDNELCB0ZXhlbFNpemUueSApLCBkcCApO1xcblxcdFxcdCNlbmRpZlxcblxcdH1cXG4jZW5kaWZcXG5cIjtcblxudmFyIHNoYWRvd21hcF9wYXJzX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9TSEFET1dNQVBcXG5cXHQjaWYgTlVNX0RJUl9MSUdIVFMgPiAwXFxuXFx0XFx0dW5pZm9ybSBtYXQ0IGRpcmVjdGlvbmFsU2hhZG93TWF0cml4WyBOVU1fRElSX0xJR0hUUyBdO1xcblxcdFxcdHZhcnlpbmcgdmVjNCB2RGlyZWN0aW9uYWxTaGFkb3dDb29yZFsgTlVNX0RJUl9MSUdIVFMgXTtcXG5cXHQjZW5kaWZcXG5cXHQjaWYgTlVNX1NQT1RfTElHSFRTID4gMFxcblxcdFxcdHVuaWZvcm0gbWF0NCBzcG90U2hhZG93TWF0cml4WyBOVU1fU1BPVF9MSUdIVFMgXTtcXG5cXHRcXHR2YXJ5aW5nIHZlYzQgdlNwb3RTaGFkb3dDb29yZFsgTlVNX1NQT1RfTElHSFRTIF07XFxuXFx0I2VuZGlmXFxuXFx0I2lmIE5VTV9QT0lOVF9MSUdIVFMgPiAwXFxuXFx0XFx0dW5pZm9ybSBtYXQ0IHBvaW50U2hhZG93TWF0cml4WyBOVU1fUE9JTlRfTElHSFRTIF07XFxuXFx0XFx0dmFyeWluZyB2ZWM0IHZQb2ludFNoYWRvd0Nvb3JkWyBOVU1fUE9JTlRfTElHSFRTIF07XFxuXFx0I2VuZGlmXFxuI2VuZGlmXFxuXCI7XG5cbnZhciBzaGFkb3dtYXBfdmVydGV4ID0gXCIjaWZkZWYgVVNFX1NIQURPV01BUFxcblxcdCNpZiBOVU1fRElSX0xJR0hUUyA+IDBcXG5cXHRmb3IgKCBpbnQgaSA9IDA7IGkgPCBOVU1fRElSX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHR2RGlyZWN0aW9uYWxTaGFkb3dDb29yZFsgaSBdID0gZGlyZWN0aW9uYWxTaGFkb3dNYXRyaXhbIGkgXSAqIHdvcmxkUG9zaXRpb247XFxuXFx0fVxcblxcdCNlbmRpZlxcblxcdCNpZiBOVU1fU1BPVF9MSUdIVFMgPiAwXFxuXFx0Zm9yICggaW50IGkgPSAwOyBpIDwgTlVNX1NQT1RfTElHSFRTOyBpICsrICkge1xcblxcdFxcdHZTcG90U2hhZG93Q29vcmRbIGkgXSA9IHNwb3RTaGFkb3dNYXRyaXhbIGkgXSAqIHdvcmxkUG9zaXRpb247XFxuXFx0fVxcblxcdCNlbmRpZlxcblxcdCNpZiBOVU1fUE9JTlRfTElHSFRTID4gMFxcblxcdGZvciAoIGludCBpID0gMDsgaSA8IE5VTV9QT0lOVF9MSUdIVFM7IGkgKysgKSB7XFxuXFx0XFx0dlBvaW50U2hhZG93Q29vcmRbIGkgXSA9IHBvaW50U2hhZG93TWF0cml4WyBpIF0gKiB3b3JsZFBvc2l0aW9uO1xcblxcdH1cXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIHNoYWRvd21hc2tfcGFyc19mcmFnbWVudCA9IFwiZmxvYXQgZ2V0U2hhZG93TWFzaygpIHtcXG5cXHRmbG9hdCBzaGFkb3cgPSAxLjA7XFxuXFx0I2lmZGVmIFVTRV9TSEFET1dNQVBcXG5cXHQjaWYgTlVNX0RJUl9MSUdIVFMgPiAwXFxuXFx0RGlyZWN0aW9uYWxMaWdodCBkaXJlY3Rpb25hbExpZ2h0O1xcblxcdGZvciAoIGludCBpID0gMDsgaSA8IE5VTV9ESVJfTElHSFRTOyBpICsrICkge1xcblxcdFxcdGRpcmVjdGlvbmFsTGlnaHQgPSBkaXJlY3Rpb25hbExpZ2h0c1sgaSBdO1xcblxcdFxcdHNoYWRvdyAqPSBib29sKCBkaXJlY3Rpb25hbExpZ2h0LnNoYWRvdyApID8gZ2V0U2hhZG93KCBkaXJlY3Rpb25hbFNoYWRvd01hcFsgaSBdLCBkaXJlY3Rpb25hbExpZ2h0LnNoYWRvd01hcFNpemUsIGRpcmVjdGlvbmFsTGlnaHQuc2hhZG93QmlhcywgZGlyZWN0aW9uYWxMaWdodC5zaGFkb3dSYWRpdXMsIHZEaXJlY3Rpb25hbFNoYWRvd0Nvb3JkWyBpIF0gKSA6IDEuMDtcXG5cXHR9XFxuXFx0I2VuZGlmXFxuXFx0I2lmIE5VTV9TUE9UX0xJR0hUUyA+IDBcXG5cXHRTcG90TGlnaHQgc3BvdExpZ2h0O1xcblxcdGZvciAoIGludCBpID0gMDsgaSA8IE5VTV9TUE9UX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHRzcG90TGlnaHQgPSBzcG90TGlnaHRzWyBpIF07XFxuXFx0XFx0c2hhZG93ICo9IGJvb2woIHNwb3RMaWdodC5zaGFkb3cgKSA/IGdldFNoYWRvdyggc3BvdFNoYWRvd01hcFsgaSBdLCBzcG90TGlnaHQuc2hhZG93TWFwU2l6ZSwgc3BvdExpZ2h0LnNoYWRvd0JpYXMsIHNwb3RMaWdodC5zaGFkb3dSYWRpdXMsIHZTcG90U2hhZG93Q29vcmRbIGkgXSApIDogMS4wO1xcblxcdH1cXG5cXHQjZW5kaWZcXG5cXHQjaWYgTlVNX1BPSU5UX0xJR0hUUyA+IDBcXG5cXHRQb2ludExpZ2h0IHBvaW50TGlnaHQ7XFxuXFx0Zm9yICggaW50IGkgPSAwOyBpIDwgTlVNX1BPSU5UX0xJR0hUUzsgaSArKyApIHtcXG5cXHRcXHRwb2ludExpZ2h0ID0gcG9pbnRMaWdodHNbIGkgXTtcXG5cXHRcXHRzaGFkb3cgKj0gYm9vbCggcG9pbnRMaWdodC5zaGFkb3cgKSA/IGdldFBvaW50U2hhZG93KCBwb2ludFNoYWRvd01hcFsgaSBdLCBwb2ludExpZ2h0LnNoYWRvd01hcFNpemUsIHBvaW50TGlnaHQuc2hhZG93QmlhcywgcG9pbnRMaWdodC5zaGFkb3dSYWRpdXMsIHZQb2ludFNoYWRvd0Nvb3JkWyBpIF0gKSA6IDEuMDtcXG5cXHR9XFxuXFx0I2VuZGlmXFxuXFx0I2VuZGlmXFxuXFx0cmV0dXJuIHNoYWRvdztcXG59XFxuXCI7XG5cbnZhciBza2luYmFzZV92ZXJ0ZXggPSBcIiNpZmRlZiBVU0VfU0tJTk5JTkdcXG5cXHRtYXQ0IGJvbmVNYXRYID0gZ2V0Qm9uZU1hdHJpeCggc2tpbkluZGV4LnggKTtcXG5cXHRtYXQ0IGJvbmVNYXRZID0gZ2V0Qm9uZU1hdHJpeCggc2tpbkluZGV4LnkgKTtcXG5cXHRtYXQ0IGJvbmVNYXRaID0gZ2V0Qm9uZU1hdHJpeCggc2tpbkluZGV4LnogKTtcXG5cXHRtYXQ0IGJvbmVNYXRXID0gZ2V0Qm9uZU1hdHJpeCggc2tpbkluZGV4LncgKTtcXG4jZW5kaWZcIjtcblxudmFyIHNraW5uaW5nX3BhcnNfdmVydGV4ID0gXCIjaWZkZWYgVVNFX1NLSU5OSU5HXFxuXFx0dW5pZm9ybSBtYXQ0IGJpbmRNYXRyaXg7XFxuXFx0dW5pZm9ybSBtYXQ0IGJpbmRNYXRyaXhJbnZlcnNlO1xcblxcdCNpZmRlZiBCT05FX1RFWFRVUkVcXG5cXHRcXHR1bmlmb3JtIHNhbXBsZXIyRCBib25lVGV4dHVyZTtcXG5cXHRcXHR1bmlmb3JtIGludCBib25lVGV4dHVyZVNpemU7XFxuXFx0XFx0bWF0NCBnZXRCb25lTWF0cml4KCBjb25zdCBpbiBmbG9hdCBpICkge1xcblxcdFxcdFxcdGZsb2F0IGogPSBpICogNC4wO1xcblxcdFxcdFxcdGZsb2F0IHggPSBtb2QoIGosIGZsb2F0KCBib25lVGV4dHVyZVNpemUgKSApO1xcblxcdFxcdFxcdGZsb2F0IHkgPSBmbG9vciggaiAvIGZsb2F0KCBib25lVGV4dHVyZVNpemUgKSApO1xcblxcdFxcdFxcdGZsb2F0IGR4ID0gMS4wIC8gZmxvYXQoIGJvbmVUZXh0dXJlU2l6ZSApO1xcblxcdFxcdFxcdGZsb2F0IGR5ID0gMS4wIC8gZmxvYXQoIGJvbmVUZXh0dXJlU2l6ZSApO1xcblxcdFxcdFxcdHkgPSBkeSAqICggeSArIDAuNSApO1xcblxcdFxcdFxcdHZlYzQgdjEgPSB0ZXh0dXJlMkQoIGJvbmVUZXh0dXJlLCB2ZWMyKCBkeCAqICggeCArIDAuNSApLCB5ICkgKTtcXG5cXHRcXHRcXHR2ZWM0IHYyID0gdGV4dHVyZTJEKCBib25lVGV4dHVyZSwgdmVjMiggZHggKiAoIHggKyAxLjUgKSwgeSApICk7XFxuXFx0XFx0XFx0dmVjNCB2MyA9IHRleHR1cmUyRCggYm9uZVRleHR1cmUsIHZlYzIoIGR4ICogKCB4ICsgMi41ICksIHkgKSApO1xcblxcdFxcdFxcdHZlYzQgdjQgPSB0ZXh0dXJlMkQoIGJvbmVUZXh0dXJlLCB2ZWMyKCBkeCAqICggeCArIDMuNSApLCB5ICkgKTtcXG5cXHRcXHRcXHRtYXQ0IGJvbmUgPSBtYXQ0KCB2MSwgdjIsIHYzLCB2NCApO1xcblxcdFxcdFxcdHJldHVybiBib25lO1xcblxcdFxcdH1cXG5cXHQjZWxzZVxcblxcdFxcdHVuaWZvcm0gbWF0NCBib25lTWF0cmljZXNbIE1BWF9CT05FUyBdO1xcblxcdFxcdG1hdDQgZ2V0Qm9uZU1hdHJpeCggY29uc3QgaW4gZmxvYXQgaSApIHtcXG5cXHRcXHRcXHRtYXQ0IGJvbmUgPSBib25lTWF0cmljZXNbIGludChpKSBdO1xcblxcdFxcdFxcdHJldHVybiBib25lO1xcblxcdFxcdH1cXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIHNraW5uaW5nX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9TS0lOTklOR1xcblxcdHZlYzQgc2tpblZlcnRleCA9IGJpbmRNYXRyaXggKiB2ZWM0KCB0cmFuc2Zvcm1lZCwgMS4wICk7XFxuXFx0dmVjNCBza2lubmVkID0gdmVjNCggMC4wICk7XFxuXFx0c2tpbm5lZCArPSBib25lTWF0WCAqIHNraW5WZXJ0ZXggKiBza2luV2VpZ2h0Lng7XFxuXFx0c2tpbm5lZCArPSBib25lTWF0WSAqIHNraW5WZXJ0ZXggKiBza2luV2VpZ2h0Lnk7XFxuXFx0c2tpbm5lZCArPSBib25lTWF0WiAqIHNraW5WZXJ0ZXggKiBza2luV2VpZ2h0Lno7XFxuXFx0c2tpbm5lZCArPSBib25lTWF0VyAqIHNraW5WZXJ0ZXggKiBza2luV2VpZ2h0Lnc7XFxuXFx0c2tpbm5lZCAgPSBiaW5kTWF0cml4SW52ZXJzZSAqIHNraW5uZWQ7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciBza2lubm9ybWFsX3ZlcnRleCA9IFwiI2lmZGVmIFVTRV9TS0lOTklOR1xcblxcdG1hdDQgc2tpbk1hdHJpeCA9IG1hdDQoIDAuMCApO1xcblxcdHNraW5NYXRyaXggKz0gc2tpbldlaWdodC54ICogYm9uZU1hdFg7XFxuXFx0c2tpbk1hdHJpeCArPSBza2luV2VpZ2h0LnkgKiBib25lTWF0WTtcXG5cXHRza2luTWF0cml4ICs9IHNraW5XZWlnaHQueiAqIGJvbmVNYXRaO1xcblxcdHNraW5NYXRyaXggKz0gc2tpbldlaWdodC53ICogYm9uZU1hdFc7XFxuXFx0c2tpbk1hdHJpeCAgPSBiaW5kTWF0cml4SW52ZXJzZSAqIHNraW5NYXRyaXggKiBiaW5kTWF0cml4O1xcblxcdG9iamVjdE5vcm1hbCA9IHZlYzQoIHNraW5NYXRyaXggKiB2ZWM0KCBvYmplY3ROb3JtYWwsIDAuMCApICkueHl6O1xcbiNlbmRpZlxcblwiO1xuXG52YXIgc3BlY3VsYXJtYXBfZnJhZ21lbnQgPSBcImZsb2F0IHNwZWN1bGFyU3RyZW5ndGg7XFxuI2lmZGVmIFVTRV9TUEVDVUxBUk1BUFxcblxcdHZlYzQgdGV4ZWxTcGVjdWxhciA9IHRleHR1cmUyRCggc3BlY3VsYXJNYXAsIHZVdiApO1xcblxcdHNwZWN1bGFyU3RyZW5ndGggPSB0ZXhlbFNwZWN1bGFyLnI7XFxuI2Vsc2VcXG5cXHRzcGVjdWxhclN0cmVuZ3RoID0gMS4wO1xcbiNlbmRpZlwiO1xuXG52YXIgc3BlY3VsYXJtYXBfcGFyc19mcmFnbWVudCA9IFwiI2lmZGVmIFVTRV9TUEVDVUxBUk1BUFxcblxcdHVuaWZvcm0gc2FtcGxlcjJEIHNwZWN1bGFyTWFwO1xcbiNlbmRpZlwiO1xuXG52YXIgdG9uZW1hcHBpbmdfZnJhZ21lbnQgPSBcIiNpZiBkZWZpbmVkKCBUT05FX01BUFBJTkcgKVxcbiAgZ2xfRnJhZ0NvbG9yLnJnYiA9IHRvbmVNYXBwaW5nKCBnbF9GcmFnQ29sb3IucmdiICk7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciB0b25lbWFwcGluZ19wYXJzX2ZyYWdtZW50ID0gXCIjZGVmaW5lIHNhdHVyYXRlKGEpIGNsYW1wKCBhLCAwLjAsIDEuMCApXFxudW5pZm9ybSBmbG9hdCB0b25lTWFwcGluZ0V4cG9zdXJlO1xcbnVuaWZvcm0gZmxvYXQgdG9uZU1hcHBpbmdXaGl0ZVBvaW50O1xcbnZlYzMgTGluZWFyVG9uZU1hcHBpbmcoIHZlYzMgY29sb3IgKSB7XFxuXFx0cmV0dXJuIHRvbmVNYXBwaW5nRXhwb3N1cmUgKiBjb2xvcjtcXG59XFxudmVjMyBSZWluaGFyZFRvbmVNYXBwaW5nKCB2ZWMzIGNvbG9yICkge1xcblxcdGNvbG9yICo9IHRvbmVNYXBwaW5nRXhwb3N1cmU7XFxuXFx0cmV0dXJuIHNhdHVyYXRlKCBjb2xvciAvICggdmVjMyggMS4wICkgKyBjb2xvciApICk7XFxufVxcbiNkZWZpbmUgVW5jaGFydGVkMkhlbHBlciggeCApIG1heCggKCAoIHggKiAoIDAuMTUgKiB4ICsgMC4xMCAqIDAuNTAgKSArIDAuMjAgKiAwLjAyICkgLyAoIHggKiAoIDAuMTUgKiB4ICsgMC41MCApICsgMC4yMCAqIDAuMzAgKSApIC0gMC4wMiAvIDAuMzAsIHZlYzMoIDAuMCApIClcXG52ZWMzIFVuY2hhcnRlZDJUb25lTWFwcGluZyggdmVjMyBjb2xvciApIHtcXG5cXHRjb2xvciAqPSB0b25lTWFwcGluZ0V4cG9zdXJlO1xcblxcdHJldHVybiBzYXR1cmF0ZSggVW5jaGFydGVkMkhlbHBlciggY29sb3IgKSAvIFVuY2hhcnRlZDJIZWxwZXIoIHZlYzMoIHRvbmVNYXBwaW5nV2hpdGVQb2ludCApICkgKTtcXG59XFxudmVjMyBPcHRpbWl6ZWRDaW5lb25Ub25lTWFwcGluZyggdmVjMyBjb2xvciApIHtcXG5cXHRjb2xvciAqPSB0b25lTWFwcGluZ0V4cG9zdXJlO1xcblxcdGNvbG9yID0gbWF4KCB2ZWMzKCAwLjAgKSwgY29sb3IgLSAwLjAwNCApO1xcblxcdHJldHVybiBwb3coICggY29sb3IgKiAoIDYuMiAqIGNvbG9yICsgMC41ICkgKSAvICggY29sb3IgKiAoIDYuMiAqIGNvbG9yICsgMS43ICkgKyAwLjA2ICksIHZlYzMoIDIuMiApICk7XFxufVxcblwiO1xuXG52YXIgdXZfcGFyc19mcmFnbWVudCA9IFwiI2lmIGRlZmluZWQoIFVTRV9NQVAgKSB8fCBkZWZpbmVkKCBVU0VfQlVNUE1BUCApIHx8IGRlZmluZWQoIFVTRV9OT1JNQUxNQVAgKSB8fCBkZWZpbmVkKCBVU0VfU1BFQ1VMQVJNQVAgKSB8fCBkZWZpbmVkKCBVU0VfQUxQSEFNQVAgKSB8fCBkZWZpbmVkKCBVU0VfRU1JU1NJVkVNQVAgKSB8fCBkZWZpbmVkKCBVU0VfUk9VR0hORVNTTUFQICkgfHwgZGVmaW5lZCggVVNFX01FVEFMTkVTU01BUCApXFxuXFx0dmFyeWluZyB2ZWMyIHZVdjtcXG4jZW5kaWZcIjtcblxudmFyIHV2X3BhcnNfdmVydGV4ID0gXCIjaWYgZGVmaW5lZCggVVNFX01BUCApIHx8IGRlZmluZWQoIFVTRV9CVU1QTUFQICkgfHwgZGVmaW5lZCggVVNFX05PUk1BTE1BUCApIHx8IGRlZmluZWQoIFVTRV9TUEVDVUxBUk1BUCApIHx8IGRlZmluZWQoIFVTRV9BTFBIQU1BUCApIHx8IGRlZmluZWQoIFVTRV9FTUlTU0lWRU1BUCApIHx8IGRlZmluZWQoIFVTRV9ST1VHSE5FU1NNQVAgKSB8fCBkZWZpbmVkKCBVU0VfTUVUQUxORVNTTUFQIClcXG5cXHR2YXJ5aW5nIHZlYzIgdlV2O1xcblxcdHVuaWZvcm0gdmVjNCBvZmZzZXRSZXBlYXQ7XFxuI2VuZGlmXFxuXCI7XG5cbnZhciB1dl92ZXJ0ZXggPSBcIiNpZiBkZWZpbmVkKCBVU0VfTUFQICkgfHwgZGVmaW5lZCggVVNFX0JVTVBNQVAgKSB8fCBkZWZpbmVkKCBVU0VfTk9STUFMTUFQICkgfHwgZGVmaW5lZCggVVNFX1NQRUNVTEFSTUFQICkgfHwgZGVmaW5lZCggVVNFX0FMUEhBTUFQICkgfHwgZGVmaW5lZCggVVNFX0VNSVNTSVZFTUFQICkgfHwgZGVmaW5lZCggVVNFX1JPVUdITkVTU01BUCApIHx8IGRlZmluZWQoIFVTRV9NRVRBTE5FU1NNQVAgKVxcblxcdHZVdiA9IHV2ICogb2Zmc2V0UmVwZWF0Lnp3ICsgb2Zmc2V0UmVwZWF0Lnh5O1xcbiNlbmRpZlwiO1xuXG52YXIgdXYyX3BhcnNfZnJhZ21lbnQgPSBcIiNpZiBkZWZpbmVkKCBVU0VfTElHSFRNQVAgKSB8fCBkZWZpbmVkKCBVU0VfQU9NQVAgKVxcblxcdHZhcnlpbmcgdmVjMiB2VXYyO1xcbiNlbmRpZlwiO1xuXG52YXIgdXYyX3BhcnNfdmVydGV4ID0gXCIjaWYgZGVmaW5lZCggVVNFX0xJR0hUTUFQICkgfHwgZGVmaW5lZCggVVNFX0FPTUFQIClcXG5cXHRhdHRyaWJ1dGUgdmVjMiB1djI7XFxuXFx0dmFyeWluZyB2ZWMyIHZVdjI7XFxuI2VuZGlmXCI7XG5cbnZhciB1djJfdmVydGV4ID0gXCIjaWYgZGVmaW5lZCggVVNFX0xJR0hUTUFQICkgfHwgZGVmaW5lZCggVVNFX0FPTUFQIClcXG5cXHR2VXYyID0gdXYyO1xcbiNlbmRpZlwiO1xuXG52YXIgd29ybGRwb3NfdmVydGV4ID0gXCIjaWYgZGVmaW5lZCggVVNFX0VOVk1BUCApIHx8IGRlZmluZWQoIFBIT05HICkgfHwgZGVmaW5lZCggUEhZU0lDQUwgKSB8fCBkZWZpbmVkKCBMQU1CRVJUICkgfHwgZGVmaW5lZCAoIFVTRV9TSEFET1dNQVAgKVxcblxcdCNpZmRlZiBVU0VfU0tJTk5JTkdcXG5cXHRcXHR2ZWM0IHdvcmxkUG9zaXRpb24gPSBtb2RlbE1hdHJpeCAqIHNraW5uZWQ7XFxuXFx0I2Vsc2VcXG5cXHRcXHR2ZWM0IHdvcmxkUG9zaXRpb24gPSBtb2RlbE1hdHJpeCAqIHZlYzQoIHRyYW5zZm9ybWVkLCAxLjAgKTtcXG5cXHQjZW5kaWZcXG4jZW5kaWZcXG5cIjtcblxudmFyIGN1YmVfZnJhZyA9IFwidW5pZm9ybSBzYW1wbGVyQ3ViZSB0Q3ViZTtcXG51bmlmb3JtIGZsb2F0IHRGbGlwO1xcbnVuaWZvcm0gZmxvYXQgb3BhY2l0eTtcXG52YXJ5aW5nIHZlYzMgdldvcmxkUG9zaXRpb247XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG52b2lkIG1haW4oKSB7XFxuXFx0Z2xfRnJhZ0NvbG9yID0gdGV4dHVyZUN1YmUoIHRDdWJlLCB2ZWMzKCB0RmxpcCAqIHZXb3JsZFBvc2l0aW9uLngsIHZXb3JsZFBvc2l0aW9uLnl6ICkgKTtcXG5cXHRnbF9GcmFnQ29sb3IuYSAqPSBvcGFjaXR5O1xcbn1cXG5cIjtcblxudmFyIGN1YmVfdmVydCA9IFwidmFyeWluZyB2ZWMzIHZXb3JsZFBvc2l0aW9uO1xcbiNpbmNsdWRlIDxjb21tb24+XFxudm9pZCBtYWluKCkge1xcblxcdHZXb3JsZFBvc2l0aW9uID0gdHJhbnNmb3JtRGlyZWN0aW9uKCBwb3NpdGlvbiwgbW9kZWxNYXRyaXggKTtcXG5cXHQjaW5jbHVkZSA8YmVnaW5fdmVydGV4PlxcblxcdCNpbmNsdWRlIDxwcm9qZWN0X3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBkZXB0aF9mcmFnID0gXCIjaWYgREVQVEhfUEFDS0lORyA9PSAzMjAwXFxuXFx0dW5pZm9ybSBmbG9hdCBvcGFjaXR5O1xcbiNlbmRpZlxcbiNpbmNsdWRlIDxjb21tb24+XFxuI2luY2x1ZGUgPHBhY2tpbmc+XFxuI2luY2x1ZGUgPHV2X3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxhbHBoYW1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfcGFyc19mcmFnbWVudD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19mcmFnbWVudD5cXG5cXHR2ZWM0IGRpZmZ1c2VDb2xvciA9IHZlYzQoIDEuMCApO1xcblxcdCNpZiBERVBUSF9QQUNLSU5HID09IDMyMDBcXG5cXHRcXHRkaWZmdXNlQ29sb3IuYSA9IG9wYWNpdHk7XFxuXFx0I2VuZGlmXFxuXFx0I2luY2x1ZGUgPG1hcF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8YWxwaGFtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGFscGhhdGVzdF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bG9nZGVwdGhidWZfZnJhZ21lbnQ+XFxuXFx0I2lmIERFUFRIX1BBQ0tJTkcgPT0gMzIwMFxcblxcdFxcdGdsX0ZyYWdDb2xvciA9IHZlYzQoIHZlYzMoIGdsX0ZyYWdDb29yZC56ICksIG9wYWNpdHkgKTtcXG5cXHQjZWxpZiBERVBUSF9QQUNLSU5HID09IDMyMDFcXG5cXHRcXHRnbF9GcmFnQ29sb3IgPSBwYWNrRGVwdGhUb1JHQkEoIGdsX0ZyYWdDb29yZC56ICk7XFxuXFx0I2VuZGlmXFxufVxcblwiO1xuXG52YXIgZGVwdGhfdmVydCA9IFwiI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8dXZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGRpc3BsYWNlbWVudG1hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bW9ycGh0YXJnZXRfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHNraW5uaW5nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfdmVydGV4PlxcbnZvaWQgbWFpbigpIHtcXG5cXHQjaW5jbHVkZSA8dXZfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2luYmFzZV92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGlzcGxhY2VtZW50bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGh0YXJnZXRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubmluZ192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxufVxcblwiO1xuXG52YXIgZGlzdGFuY2VSR0JBX2ZyYWcgPSBcInVuaWZvcm0gdmVjMyBsaWdodFBvcztcXG52YXJ5aW5nIHZlYzQgdldvcmxkUG9zaXRpb247XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8cGFja2luZz5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluICgpIHtcXG5cXHQjaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX2ZyYWdtZW50PlxcblxcdGdsX0ZyYWdDb2xvciA9IHBhY2tEZXB0aFRvUkdCQSggbGVuZ3RoKCB2V29ybGRQb3NpdGlvbi54eXogLSBsaWdodFBvcy54eXogKSAvIDEwMDAuMCApO1xcbn1cXG5cIjtcblxudmFyIGRpc3RhbmNlUkdCQV92ZXJ0ID0gXCJ2YXJ5aW5nIHZlYzQgdldvcmxkUG9zaXRpb247XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8bW9ycGh0YXJnZXRfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHNraW5uaW5nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfcGFyc192ZXJ0ZXg+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxza2luYmFzZV92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGh0YXJnZXRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubmluZ192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4PlxcblxcdCNpbmNsdWRlIDx3b3JsZHBvc192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxuXFx0dldvcmxkUG9zaXRpb24gPSB3b3JsZFBvc2l0aW9uO1xcbn1cXG5cIjtcblxudmFyIGVxdWlyZWN0X2ZyYWcgPSBcInVuaWZvcm0gc2FtcGxlcjJEIHRFcXVpcmVjdDtcXG51bmlmb3JtIGZsb2F0IHRGbGlwO1xcbnZhcnlpbmcgdmVjMyB2V29ybGRQb3NpdGlvbjtcXG4jaW5jbHVkZSA8Y29tbW9uPlxcbnZvaWQgbWFpbigpIHtcXG5cXHR2ZWMzIGRpcmVjdGlvbiA9IG5vcm1hbGl6ZSggdldvcmxkUG9zaXRpb24gKTtcXG5cXHR2ZWMyIHNhbXBsZVVWO1xcblxcdHNhbXBsZVVWLnkgPSBzYXR1cmF0ZSggdEZsaXAgKiBkaXJlY3Rpb24ueSAqIC0wLjUgKyAwLjUgKTtcXG5cXHRzYW1wbGVVVi54ID0gYXRhbiggZGlyZWN0aW9uLnosIGRpcmVjdGlvbi54ICkgKiBSRUNJUFJPQ0FMX1BJMiArIDAuNTtcXG5cXHRnbF9GcmFnQ29sb3IgPSB0ZXh0dXJlMkQoIHRFcXVpcmVjdCwgc2FtcGxlVVYgKTtcXG59XFxuXCI7XG5cbnZhciBlcXVpcmVjdF92ZXJ0ID0gXCJ2YXJ5aW5nIHZlYzMgdldvcmxkUG9zaXRpb247XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG52b2lkIG1haW4oKSB7XFxuXFx0dldvcmxkUG9zaXRpb24gPSB0cmFuc2Zvcm1EaXJlY3Rpb24oIHBvc2l0aW9uLCBtb2RlbE1hdHJpeCApO1xcblxcdCNpbmNsdWRlIDxiZWdpbl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4Plxcbn1cXG5cIjtcblxudmFyIGxpbmVkYXNoZWRfZnJhZyA9IFwidW5pZm9ybSB2ZWMzIGRpZmZ1c2U7XFxudW5pZm9ybSBmbG9hdCBvcGFjaXR5O1xcbnVuaWZvcm0gZmxvYXQgZGFzaFNpemU7XFxudW5pZm9ybSBmbG9hdCB0b3RhbFNpemU7XFxudmFyeWluZyBmbG9hdCB2TGluZURpc3RhbmNlO1xcbiNpbmNsdWRlIDxjb21tb24+XFxuI2luY2x1ZGUgPGNvbG9yX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGZvZ19wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfcGFyc19mcmFnbWVudD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19mcmFnbWVudD5cXG5cXHRpZiAoIG1vZCggdkxpbmVEaXN0YW5jZSwgdG90YWxTaXplICkgPiBkYXNoU2l6ZSApIHtcXG5cXHRcXHRkaXNjYXJkO1xcblxcdH1cXG5cXHR2ZWMzIG91dGdvaW5nTGlnaHQgPSB2ZWMzKCAwLjAgKTtcXG5cXHR2ZWM0IGRpZmZ1c2VDb2xvciA9IHZlYzQoIGRpZmZ1c2UsIG9wYWNpdHkgKTtcXG5cXHQjaW5jbHVkZSA8bG9nZGVwdGhidWZfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGNvbG9yX2ZyYWdtZW50PlxcblxcdG91dGdvaW5nTGlnaHQgPSBkaWZmdXNlQ29sb3IucmdiO1xcblxcdGdsX0ZyYWdDb2xvciA9IHZlYzQoIG91dGdvaW5nTGlnaHQsIGRpZmZ1c2VDb2xvci5hICk7XFxuXFx0I2luY2x1ZGUgPHByZW11bHRpcGxpZWRfYWxwaGFfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPHRvbmVtYXBwaW5nX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxlbmNvZGluZ3NfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGZvZ19mcmFnbWVudD5cXG59XFxuXCI7XG5cbnZhciBsaW5lZGFzaGVkX3ZlcnQgPSBcInVuaWZvcm0gZmxvYXQgc2NhbGU7XFxuYXR0cmlidXRlIGZsb2F0IGxpbmVEaXN0YW5jZTtcXG52YXJ5aW5nIGZsb2F0IHZMaW5lRGlzdGFuY2U7XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8Y29sb3JfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGZvZ19wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPGNvbG9yX3ZlcnRleD5cXG5cXHR2TGluZURpc3RhbmNlID0gc2NhbGUgKiBsaW5lRGlzdGFuY2U7XFxuXFx0dmVjNCBtdlBvc2l0aW9uID0gbW9kZWxWaWV3TWF0cml4ICogdmVjNCggcG9zaXRpb24sIDEuMCApO1xcblxcdGdsX1Bvc2l0aW9uID0gcHJvamVjdGlvbk1hdHJpeCAqIG12UG9zaXRpb247XFxuXFx0I2luY2x1ZGUgPGxvZ2RlcHRoYnVmX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Zm9nX3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBtZXNoYmFzaWNfZnJhZyA9IFwidW5pZm9ybSB2ZWMzIGRpZmZ1c2U7XFxudW5pZm9ybSBmbG9hdCBvcGFjaXR5O1xcbiNpZm5kZWYgRkxBVF9TSEFERURcXG5cXHR2YXJ5aW5nIHZlYzMgdk5vcm1hbDtcXG4jZW5kaWZcXG4jaW5jbHVkZSA8Y29tbW9uPlxcbiNpbmNsdWRlIDxjb2xvcl9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDx1dl9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDx1djJfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGFscGhhbWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGFvbWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGxpZ2h0bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGVudm1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxmb2dfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8c3BlY3VsYXJtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQ+XFxuXFx0dmVjNCBkaWZmdXNlQ29sb3IgPSB2ZWM0KCBkaWZmdXNlLCBvcGFjaXR5ICk7XFxuXFx0I2luY2x1ZGUgPGxvZ2RlcHRoYnVmX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGNvbG9yX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxhbHBoYW1hcF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8YWxwaGF0ZXN0X2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxzcGVjdWxhcm1hcF9mcmFnbWVudD5cXG5cXHRSZWZsZWN0ZWRMaWdodCByZWZsZWN0ZWRMaWdodCA9IFJlZmxlY3RlZExpZ2h0KCB2ZWMzKCAwLjAgKSwgdmVjMyggMC4wICksIHZlYzMoIDAuMCApLCB2ZWMzKCAwLjAgKSApO1xcblxcdCNpZmRlZiBVU0VfTElHSFRNQVBcXG5cXHRcXHRyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2UgKz0gdGV4dHVyZTJEKCBsaWdodE1hcCwgdlV2MiApLnh5eiAqIGxpZ2h0TWFwSW50ZW5zaXR5O1xcblxcdCNlbHNlXFxuXFx0XFx0cmVmbGVjdGVkTGlnaHQuaW5kaXJlY3REaWZmdXNlICs9IHZlYzMoIDEuMCApO1xcblxcdCNlbmRpZlxcblxcdCNpbmNsdWRlIDxhb21hcF9mcmFnbWVudD5cXG5cXHRyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2UgKj0gZGlmZnVzZUNvbG9yLnJnYjtcXG5cXHR2ZWMzIG91dGdvaW5nTGlnaHQgPSByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2U7XFxuXFx0I2luY2x1ZGUgPG5vcm1hbF9mbGlwPlxcblxcdCNpbmNsdWRlIDxlbnZtYXBfZnJhZ21lbnQ+XFxuXFx0Z2xfRnJhZ0NvbG9yID0gdmVjNCggb3V0Z29pbmdMaWdodCwgZGlmZnVzZUNvbG9yLmEgKTtcXG5cXHQjaW5jbHVkZSA8cHJlbXVsdGlwbGllZF9hbHBoYV9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8dG9uZW1hcHBpbmdfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGVuY29kaW5nc19mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8Zm9nX2ZyYWdtZW50Plxcbn1cXG5cIjtcblxudmFyIG1lc2hiYXNpY192ZXJ0ID0gXCIjaW5jbHVkZSA8Y29tbW9uPlxcbiNpbmNsdWRlIDx1dl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8dXYyX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxlbnZtYXBfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNvbG9yX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxmb2dfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPG1vcnBodGFyZ2V0X3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxza2lubmluZ19wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPHV2X3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8dXYyX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Y29sb3JfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2luYmFzZV92ZXJ0ZXg+XFxuXFx0I2lmZGVmIFVTRV9FTlZNQVBcXG5cXHQjaW5jbHVkZSA8YmVnaW5ub3JtYWxfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxtb3JwaG5vcm1hbF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHNraW5ub3JtYWxfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxkZWZhdWx0bm9ybWFsX3ZlcnRleD5cXG5cXHQjZW5kaWZcXG5cXHQjaW5jbHVkZSA8YmVnaW5fdmVydGV4PlxcblxcdCNpbmNsdWRlIDxtb3JwaHRhcmdldF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHNraW5uaW5nX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8cHJvamVjdF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGxvZ2RlcHRoYnVmX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8d29ybGRwb3NfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxlbnZtYXBfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxmb2dfdmVydGV4Plxcbn1cXG5cIjtcblxudmFyIG1lc2hsYW1iZXJ0X2ZyYWcgPSBcInVuaWZvcm0gdmVjMyBkaWZmdXNlO1xcbnVuaWZvcm0gdmVjMyBlbWlzc2l2ZTtcXG51bmlmb3JtIGZsb2F0IG9wYWNpdHk7XFxudmFyeWluZyB2ZWMzIHZMaWdodEZyb250O1xcbiNpZmRlZiBET1VCTEVfU0lERURcXG5cXHR2YXJ5aW5nIHZlYzMgdkxpZ2h0QmFjaztcXG4jZW5kaWZcXG4jaW5jbHVkZSA8Y29tbW9uPlxcbiNpbmNsdWRlIDxwYWNraW5nPlxcbiNpbmNsdWRlIDxkaXRoZXJpbmdfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y29sb3JfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8dXZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8dXYyX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxhbHBoYW1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxhb21hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxsaWdodG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxlbWlzc2l2ZW1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxlbnZtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8YnNkZnM+XFxuI2luY2x1ZGUgPGxpZ2h0c19wYXJzPlxcbiNpbmNsdWRlIDxmb2dfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8c2hhZG93bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPHNoYWRvd21hc2tfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8c3BlY3VsYXJtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQ+XFxuXFx0dmVjNCBkaWZmdXNlQ29sb3IgPSB2ZWM0KCBkaWZmdXNlLCBvcGFjaXR5ICk7XFxuXFx0UmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgPSBSZWZsZWN0ZWRMaWdodCggdmVjMyggMC4wICksIHZlYzMoIDAuMCApLCB2ZWMzKCAwLjAgKSwgdmVjMyggMC4wICkgKTtcXG5cXHR2ZWMzIHRvdGFsRW1pc3NpdmVSYWRpYW5jZSA9IGVtaXNzaXZlO1xcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bWFwX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxjb2xvcl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8YWxwaGFtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGFscGhhdGVzdF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8c3BlY3VsYXJtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGVtaXNzaXZlbWFwX2ZyYWdtZW50PlxcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSA9IGdldEFtYmllbnRMaWdodElycmFkaWFuY2UoIGFtYmllbnRMaWdodENvbG9yICk7XFxuXFx0I2luY2x1ZGUgPGxpZ2h0bWFwX2ZyYWdtZW50PlxcblxcdHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSAqPSBCUkRGX0RpZmZ1c2VfTGFtYmVydCggZGlmZnVzZUNvbG9yLnJnYiApO1xcblxcdCNpZmRlZiBET1VCTEVfU0lERURcXG5cXHRcXHRyZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlID0gKCBnbF9Gcm9udEZhY2luZyApID8gdkxpZ2h0RnJvbnQgOiB2TGlnaHRCYWNrO1xcblxcdCNlbHNlXFxuXFx0XFx0cmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSA9IHZMaWdodEZyb250O1xcblxcdCNlbmRpZlxcblxcdHJlZmxlY3RlZExpZ2h0LmRpcmVjdERpZmZ1c2UgKj0gQlJERl9EaWZmdXNlX0xhbWJlcnQoIGRpZmZ1c2VDb2xvci5yZ2IgKSAqIGdldFNoYWRvd01hc2soKTtcXG5cXHQjaW5jbHVkZSA8YW9tYXBfZnJhZ21lbnQ+XFxuXFx0dmVjMyBvdXRnb2luZ0xpZ2h0ID0gcmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSArIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSArIHRvdGFsRW1pc3NpdmVSYWRpYW5jZTtcXG5cXHQjaW5jbHVkZSA8bm9ybWFsX2ZsaXA+XFxuXFx0I2luY2x1ZGUgPGVudm1hcF9mcmFnbWVudD5cXG5cXHRnbF9GcmFnQ29sb3IgPSB2ZWM0KCBvdXRnb2luZ0xpZ2h0LCBkaWZmdXNlQ29sb3IuYSApO1xcblxcdCNpbmNsdWRlIDx0b25lbWFwcGluZ19mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8ZW5jb2RpbmdzX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxmb2dfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPHByZW11bHRpcGxpZWRfYWxwaGFfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGRpdGhlcmluZ19mcmFnbWVudD5cXG59XFxuXCI7XG5cbnZhciBtZXNobGFtYmVydF92ZXJ0ID0gXCIjZGVmaW5lIExBTUJFUlRcXG52YXJ5aW5nIHZlYzMgdkxpZ2h0RnJvbnQ7XFxuI2lmZGVmIERPVUJMRV9TSURFRFxcblxcdHZhcnlpbmcgdmVjMyB2TGlnaHRCYWNrO1xcbiNlbmRpZlxcbiNpbmNsdWRlIDxjb21tb24+XFxuI2luY2x1ZGUgPHV2X3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDx1djJfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGVudm1hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8YnNkZnM+XFxuI2luY2x1ZGUgPGxpZ2h0c19wYXJzPlxcbiNpbmNsdWRlIDxjb2xvcl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8Zm9nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxtb3JwaHRhcmdldF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8c2tpbm5pbmdfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHNoYWRvd21hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPHV2X3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8dXYyX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Y29sb3JfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxiZWdpbm5vcm1hbF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPG1vcnBobm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2tpbmJhc2VfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGVmYXVsdG5vcm1hbF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGh0YXJnZXRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubmluZ192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHdvcmxkcG9zX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZW52bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bGlnaHRzX2xhbWJlcnRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxzaGFkb3dtYXBfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxmb2dfdmVydGV4Plxcbn1cXG5cIjtcblxudmFyIG1lc2hwaG9uZ19mcmFnID0gXCIjZGVmaW5lIFBIT05HXFxudW5pZm9ybSB2ZWMzIGRpZmZ1c2U7XFxudW5pZm9ybSB2ZWMzIGVtaXNzaXZlO1xcbnVuaWZvcm0gdmVjMyBzcGVjdWxhcjtcXG51bmlmb3JtIGZsb2F0IHNoaW5pbmVzcztcXG51bmlmb3JtIGZsb2F0IG9wYWNpdHk7XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8cGFja2luZz5cXG4jaW5jbHVkZSA8ZGl0aGVyaW5nX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGNvbG9yX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPHV2X3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPHV2Ml9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8YWxwaGFtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8YW9tYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bGlnaHRtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8ZW1pc3NpdmVtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8ZW52bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGdyYWRpZW50bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGZvZ19wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxic2Rmcz5cXG4jaW5jbHVkZSA8bGlnaHRzX3BhcnM+XFxuI2luY2x1ZGUgPGxpZ2h0c19waG9uZ19wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxzaGFkb3dtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8YnVtcG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxub3JtYWxtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8c3BlY3VsYXJtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQ+XFxuXFx0dmVjNCBkaWZmdXNlQ29sb3IgPSB2ZWM0KCBkaWZmdXNlLCBvcGFjaXR5ICk7XFxuXFx0UmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgPSBSZWZsZWN0ZWRMaWdodCggdmVjMyggMC4wICksIHZlYzMoIDAuMCApLCB2ZWMzKCAwLjAgKSwgdmVjMyggMC4wICkgKTtcXG5cXHR2ZWMzIHRvdGFsRW1pc3NpdmVSYWRpYW5jZSA9IGVtaXNzaXZlO1xcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bWFwX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxjb2xvcl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8YWxwaGFtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGFscGhhdGVzdF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8c3BlY3VsYXJtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPG5vcm1hbF9mbGlwPlxcblxcdCNpbmNsdWRlIDxub3JtYWxfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGVtaXNzaXZlbWFwX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxsaWdodHNfcGhvbmdfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGxpZ2h0c190ZW1wbGF0ZT5cXG5cXHQjaW5jbHVkZSA8YW9tYXBfZnJhZ21lbnQ+XFxuXFx0dmVjMyBvdXRnb2luZ0xpZ2h0ID0gcmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSArIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSArIHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyICsgcmVmbGVjdGVkTGlnaHQuaW5kaXJlY3RTcGVjdWxhciArIHRvdGFsRW1pc3NpdmVSYWRpYW5jZTtcXG5cXHQjaW5jbHVkZSA8ZW52bWFwX2ZyYWdtZW50PlxcblxcdGdsX0ZyYWdDb2xvciA9IHZlYzQoIG91dGdvaW5nTGlnaHQsIGRpZmZ1c2VDb2xvci5hICk7XFxuXFx0I2luY2x1ZGUgPHRvbmVtYXBwaW5nX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxlbmNvZGluZ3NfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGZvZ19mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8cHJlbXVsdGlwbGllZF9hbHBoYV9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8ZGl0aGVyaW5nX2ZyYWdtZW50Plxcbn1cXG5cIjtcblxudmFyIG1lc2hwaG9uZ192ZXJ0ID0gXCIjZGVmaW5lIFBIT05HXFxudmFyeWluZyB2ZWMzIHZWaWV3UG9zaXRpb247XFxuI2lmbmRlZiBGTEFUX1NIQURFRFxcblxcdHZhcnlpbmcgdmVjMyB2Tm9ybWFsO1xcbiNlbmRpZlxcbiNpbmNsdWRlIDxjb21tb24+XFxuI2luY2x1ZGUgPHV2X3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDx1djJfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGRpc3BsYWNlbWVudG1hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8ZW52bWFwX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxjb2xvcl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8Zm9nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxtb3JwaHRhcmdldF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8c2tpbm5pbmdfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHNoYWRvd21hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPHV2X3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8dXYyX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Y29sb3JfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxiZWdpbm5vcm1hbF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPG1vcnBobm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2tpbmJhc2VfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGVmYXVsdG5vcm1hbF92ZXJ0ZXg+XFxuI2lmbmRlZiBGTEFUX1NIQURFRFxcblxcdHZOb3JtYWwgPSBub3JtYWxpemUoIHRyYW5zZm9ybWVkTm9ybWFsICk7XFxuI2VuZGlmXFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGlzcGxhY2VtZW50bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGh0YXJnZXRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubmluZ192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxuXFx0dlZpZXdQb3NpdGlvbiA9IC0gbXZQb3NpdGlvbi54eXo7XFxuXFx0I2luY2x1ZGUgPHdvcmxkcG9zX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZW52bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2hhZG93bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Zm9nX3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBtZXNocGh5c2ljYWxfZnJhZyA9IFwiI2RlZmluZSBQSFlTSUNBTFxcbnVuaWZvcm0gdmVjMyBkaWZmdXNlO1xcbnVuaWZvcm0gdmVjMyBlbWlzc2l2ZTtcXG51bmlmb3JtIGZsb2F0IHJvdWdobmVzcztcXG51bmlmb3JtIGZsb2F0IG1ldGFsbmVzcztcXG51bmlmb3JtIGZsb2F0IG9wYWNpdHk7XFxuI2lmbmRlZiBTVEFOREFSRFxcblxcdHVuaWZvcm0gZmxvYXQgY2xlYXJDb2F0O1xcblxcdHVuaWZvcm0gZmxvYXQgY2xlYXJDb2F0Um91Z2huZXNzO1xcbiNlbmRpZlxcbnZhcnlpbmcgdmVjMyB2Vmlld1Bvc2l0aW9uO1xcbiNpZm5kZWYgRkxBVF9TSEFERURcXG5cXHR2YXJ5aW5nIHZlYzMgdk5vcm1hbDtcXG4jZW5kaWZcXG4jaW5jbHVkZSA8Y29tbW9uPlxcbiNpbmNsdWRlIDxwYWNraW5nPlxcbiNpbmNsdWRlIDxkaXRoZXJpbmdfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y29sb3JfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8dXZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8dXYyX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxhbHBoYW1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxhb21hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxsaWdodG1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxlbWlzc2l2ZW1hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxlbnZtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Zm9nX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGJzZGZzPlxcbiNpbmNsdWRlIDxjdWJlX3V2X3JlZmxlY3Rpb25fZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGxpZ2h0c19wYXJzPlxcbiNpbmNsdWRlIDxsaWdodHNfcGh5c2ljYWxfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8c2hhZG93bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGJ1bXBtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bm9ybWFsbWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPHJvdWdobmVzc21hcF9wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxtZXRhbG5lc3NtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQ+XFxuXFx0dmVjNCBkaWZmdXNlQ29sb3IgPSB2ZWM0KCBkaWZmdXNlLCBvcGFjaXR5ICk7XFxuXFx0UmVmbGVjdGVkTGlnaHQgcmVmbGVjdGVkTGlnaHQgPSBSZWZsZWN0ZWRMaWdodCggdmVjMyggMC4wICksIHZlYzMoIDAuMCApLCB2ZWMzKCAwLjAgKSwgdmVjMyggMC4wICkgKTtcXG5cXHR2ZWMzIHRvdGFsRW1pc3NpdmVSYWRpYW5jZSA9IGVtaXNzaXZlO1xcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bWFwX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxjb2xvcl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8YWxwaGFtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGFscGhhdGVzdF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8c3BlY3VsYXJtYXBfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPHJvdWdobmVzc21hcF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bWV0YWxuZXNzbWFwX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxub3JtYWxfZmxpcD5cXG5cXHQjaW5jbHVkZSA8bm9ybWFsX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxlbWlzc2l2ZW1hcF9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bGlnaHRzX3BoeXNpY2FsX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxsaWdodHNfdGVtcGxhdGU+XFxuXFx0I2luY2x1ZGUgPGFvbWFwX2ZyYWdtZW50PlxcblxcdHZlYzMgb3V0Z29pbmdMaWdodCA9IHJlZmxlY3RlZExpZ2h0LmRpcmVjdERpZmZ1c2UgKyByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2UgKyByZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhciArIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0U3BlY3VsYXIgKyB0b3RhbEVtaXNzaXZlUmFkaWFuY2U7XFxuXFx0Z2xfRnJhZ0NvbG9yID0gdmVjNCggb3V0Z29pbmdMaWdodCwgZGlmZnVzZUNvbG9yLmEgKTtcXG5cXHQjaW5jbHVkZSA8dG9uZW1hcHBpbmdfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGVuY29kaW5nc19mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8Zm9nX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxwcmVtdWx0aXBsaWVkX2FscGhhX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxkaXRoZXJpbmdfZnJhZ21lbnQ+XFxufVxcblwiO1xuXG52YXIgbWVzaHBoeXNpY2FsX3ZlcnQgPSBcIiNkZWZpbmUgUEhZU0lDQUxcXG52YXJ5aW5nIHZlYzMgdlZpZXdQb3NpdGlvbjtcXG4jaWZuZGVmIEZMQVRfU0hBREVEXFxuXFx0dmFyeWluZyB2ZWMzIHZOb3JtYWw7XFxuI2VuZGlmXFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8dXZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHV2Ml9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8ZGlzcGxhY2VtZW50bWFwX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxjb2xvcl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8Zm9nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxtb3JwaHRhcmdldF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8c2tpbm5pbmdfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPHNoYWRvd21hcF9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8c3BlY3VsYXJtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPHV2X3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8dXYyX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Y29sb3JfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxiZWdpbm5vcm1hbF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPG1vcnBobm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2tpbmJhc2VfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGVmYXVsdG5vcm1hbF92ZXJ0ZXg+XFxuI2lmbmRlZiBGTEFUX1NIQURFRFxcblxcdHZOb3JtYWwgPSBub3JtYWxpemUoIHRyYW5zZm9ybWVkTm9ybWFsICk7XFxuI2VuZGlmXFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8ZGlzcGxhY2VtZW50bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGh0YXJnZXRfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2lubmluZ192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHByb2plY3RfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxuXFx0dlZpZXdQb3NpdGlvbiA9IC0gbXZQb3NpdGlvbi54eXo7XFxuXFx0I2luY2x1ZGUgPHdvcmxkcG9zX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2hhZG93bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Zm9nX3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBub3JtYWxfZnJhZyA9IFwiI2RlZmluZSBOT1JNQUxcXG51bmlmb3JtIGZsb2F0IG9wYWNpdHk7XFxuI2lmIGRlZmluZWQoIEZMQVRfU0hBREVEICkgfHwgZGVmaW5lZCggVVNFX0JVTVBNQVAgKSB8fCBkZWZpbmVkKCBVU0VfTk9STUFMTUFQIClcXG5cXHR2YXJ5aW5nIHZlYzMgdlZpZXdQb3NpdGlvbjtcXG4jZW5kaWZcXG4jaWZuZGVmIEZMQVRfU0hBREVEXFxuXFx0dmFyeWluZyB2ZWMzIHZOb3JtYWw7XFxuI2VuZGlmXFxuI2luY2x1ZGUgPHBhY2tpbmc+XFxuI2luY2x1ZGUgPHV2X3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGJ1bXBtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bm9ybWFsbWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGxvZ2RlcHRoYnVmX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8bm9ybWFsX2ZsaXA+XFxuXFx0I2luY2x1ZGUgPG5vcm1hbF9mcmFnbWVudD5cXG5cXHRnbF9GcmFnQ29sb3IgPSB2ZWM0KCBwYWNrTm9ybWFsVG9SR0IoIG5vcm1hbCApLCBvcGFjaXR5ICk7XFxufVxcblwiO1xuXG52YXIgbm9ybWFsX3ZlcnQgPSBcIiNkZWZpbmUgTk9STUFMXFxuI2lmIGRlZmluZWQoIEZMQVRfU0hBREVEICkgfHwgZGVmaW5lZCggVVNFX0JVTVBNQVAgKSB8fCBkZWZpbmVkKCBVU0VfTk9STUFMTUFQIClcXG5cXHR2YXJ5aW5nIHZlYzMgdlZpZXdQb3NpdGlvbjtcXG4jZW5kaWZcXG4jaWZuZGVmIEZMQVRfU0hBREVEXFxuXFx0dmFyeWluZyB2ZWMzIHZOb3JtYWw7XFxuI2VuZGlmXFxuI2luY2x1ZGUgPHV2X3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxkaXNwbGFjZW1lbnRtYXBfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPG1vcnBodGFyZ2V0X3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxza2lubmluZ19wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDx1dl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGJlZ2lubm9ybWFsX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8bW9ycGhub3JtYWxfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxza2luYmFzZV92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHNraW5ub3JtYWxfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxkZWZhdWx0bm9ybWFsX3ZlcnRleD5cXG4jaWZuZGVmIEZMQVRfU0hBREVEXFxuXFx0dk5vcm1hbCA9IG5vcm1hbGl6ZSggdHJhbnNmb3JtZWROb3JtYWwgKTtcXG4jZW5kaWZcXG5cXHQjaW5jbHVkZSA8YmVnaW5fdmVydGV4PlxcblxcdCNpbmNsdWRlIDxkaXNwbGFjZW1lbnRtYXBfdmVydGV4PlxcblxcdCNpbmNsdWRlIDxtb3JwaHRhcmdldF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHNraW5uaW5nX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8cHJvamVjdF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGxvZ2RlcHRoYnVmX3ZlcnRleD5cXG4jaWYgZGVmaW5lZCggRkxBVF9TSEFERUQgKSB8fCBkZWZpbmVkKCBVU0VfQlVNUE1BUCApIHx8IGRlZmluZWQoIFVTRV9OT1JNQUxNQVAgKVxcblxcdHZWaWV3UG9zaXRpb24gPSAtIG12UG9zaXRpb24ueHl6O1xcbiNlbmRpZlxcbn1cXG5cIjtcblxudmFyIHBvaW50c19mcmFnID0gXCJ1bmlmb3JtIHZlYzMgZGlmZnVzZTtcXG51bmlmb3JtIGZsb2F0IG9wYWNpdHk7XFxuI2luY2x1ZGUgPGNvbW1vbj5cXG4jaW5jbHVkZSA8cGFja2luZz5cXG4jaW5jbHVkZSA8Y29sb3JfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bWFwX3BhcnRpY2xlX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPGZvZ19wYXJzX2ZyYWdtZW50PlxcbiNpbmNsdWRlIDxzaGFkb3dtYXBfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudD5cXG4jaW5jbHVkZSA8Y2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQ+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfZnJhZ21lbnQ+XFxuXFx0dmVjMyBvdXRnb2luZ0xpZ2h0ID0gdmVjMyggMC4wICk7XFxuXFx0dmVjNCBkaWZmdXNlQ29sb3IgPSB2ZWM0KCBkaWZmdXNlLCBvcGFjaXR5ICk7XFxuXFx0I2luY2x1ZGUgPGxvZ2RlcHRoYnVmX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxtYXBfcGFydGljbGVfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGNvbG9yX2ZyYWdtZW50PlxcblxcdCNpbmNsdWRlIDxhbHBoYXRlc3RfZnJhZ21lbnQ+XFxuXFx0b3V0Z29pbmdMaWdodCA9IGRpZmZ1c2VDb2xvci5yZ2I7XFxuXFx0Z2xfRnJhZ0NvbG9yID0gdmVjNCggb3V0Z29pbmdMaWdodCwgZGlmZnVzZUNvbG9yLmEgKTtcXG5cXHQjaW5jbHVkZSA8cHJlbXVsdGlwbGllZF9hbHBoYV9mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8dG9uZW1hcHBpbmdfZnJhZ21lbnQ+XFxuXFx0I2luY2x1ZGUgPGVuY29kaW5nc19mcmFnbWVudD5cXG5cXHQjaW5jbHVkZSA8Zm9nX2ZyYWdtZW50Plxcbn1cXG5cIjtcblxudmFyIHBvaW50c192ZXJ0ID0gXCJ1bmlmb3JtIGZsb2F0IHNpemU7XFxudW5pZm9ybSBmbG9hdCBzY2FsZTtcXG4jaW5jbHVkZSA8Y29tbW9uPlxcbiNpbmNsdWRlIDxjb2xvcl9wYXJzX3ZlcnRleD5cXG4jaW5jbHVkZSA8Zm9nX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxzaGFkb3dtYXBfcGFyc192ZXJ0ZXg+XFxuI2luY2x1ZGUgPGxvZ2RlcHRoYnVmX3BhcnNfdmVydGV4PlxcbiNpbmNsdWRlIDxjbGlwcGluZ19wbGFuZXNfcGFyc192ZXJ0ZXg+XFxudm9pZCBtYWluKCkge1xcblxcdCNpbmNsdWRlIDxjb2xvcl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8cHJvamVjdF92ZXJ0ZXg+XFxuXFx0I2lmZGVmIFVTRV9TSVpFQVRURU5VQVRJT05cXG5cXHRcXHRnbF9Qb2ludFNpemUgPSBzaXplICogKCBzY2FsZSAvIC0gbXZQb3NpdGlvbi56ICk7XFxuXFx0I2Vsc2VcXG5cXHRcXHRnbF9Qb2ludFNpemUgPSBzaXplO1xcblxcdCNlbmRpZlxcblxcdCNpbmNsdWRlIDxsb2dkZXB0aGJ1Zl92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc192ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHdvcmxkcG9zX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2hhZG93bWFwX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8Zm9nX3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBzaGFkb3dfZnJhZyA9IFwidW5pZm9ybSBmbG9hdCBvcGFjaXR5O1xcbiNpbmNsdWRlIDxjb21tb24+XFxuI2luY2x1ZGUgPHBhY2tpbmc+XFxuI2luY2x1ZGUgPGJzZGZzPlxcbiNpbmNsdWRlIDxsaWdodHNfcGFycz5cXG4jaW5jbHVkZSA8c2hhZG93bWFwX3BhcnNfZnJhZ21lbnQ+XFxuI2luY2x1ZGUgPHNoYWRvd21hc2tfcGFyc19mcmFnbWVudD5cXG52b2lkIG1haW4oKSB7XFxuXFx0Z2xfRnJhZ0NvbG9yID0gdmVjNCggMC4wLCAwLjAsIDAuMCwgb3BhY2l0eSAqICggMS4wIC0gZ2V0U2hhZG93TWFzaygpICkgKTtcXG59XFxuXCI7XG5cbnZhciBzaGFkb3dfdmVydCA9IFwiI2luY2x1ZGUgPHNoYWRvd21hcF9wYXJzX3ZlcnRleD5cXG52b2lkIG1haW4oKSB7XFxuXFx0I2luY2x1ZGUgPGJlZ2luX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8cHJvamVjdF92ZXJ0ZXg+XFxuXFx0I2luY2x1ZGUgPHdvcmxkcG9zX3ZlcnRleD5cXG5cXHQjaW5jbHVkZSA8c2hhZG93bWFwX3ZlcnRleD5cXG59XFxuXCI7XG5cbnZhciBTaGFkZXJDaHVuayA9IHtcblx0YWxwaGFtYXBfZnJhZ21lbnQ6IGFscGhhbWFwX2ZyYWdtZW50LFxuXHRhbHBoYW1hcF9wYXJzX2ZyYWdtZW50OiBhbHBoYW1hcF9wYXJzX2ZyYWdtZW50LFxuXHRhbHBoYXRlc3RfZnJhZ21lbnQ6IGFscGhhdGVzdF9mcmFnbWVudCxcblx0YW9tYXBfZnJhZ21lbnQ6IGFvbWFwX2ZyYWdtZW50LFxuXHRhb21hcF9wYXJzX2ZyYWdtZW50OiBhb21hcF9wYXJzX2ZyYWdtZW50LFxuXHRiZWdpbl92ZXJ0ZXg6IGJlZ2luX3ZlcnRleCxcblx0YmVnaW5ub3JtYWxfdmVydGV4OiBiZWdpbm5vcm1hbF92ZXJ0ZXgsXG5cdGJzZGZzOiBic2Rmcyxcblx0YnVtcG1hcF9wYXJzX2ZyYWdtZW50OiBidW1wbWFwX3BhcnNfZnJhZ21lbnQsXG5cdGNsaXBwaW5nX3BsYW5lc19mcmFnbWVudDogY2xpcHBpbmdfcGxhbmVzX2ZyYWdtZW50LFxuXHRjbGlwcGluZ19wbGFuZXNfcGFyc19mcmFnbWVudDogY2xpcHBpbmdfcGxhbmVzX3BhcnNfZnJhZ21lbnQsXG5cdGNsaXBwaW5nX3BsYW5lc19wYXJzX3ZlcnRleDogY2xpcHBpbmdfcGxhbmVzX3BhcnNfdmVydGV4LFxuXHRjbGlwcGluZ19wbGFuZXNfdmVydGV4OiBjbGlwcGluZ19wbGFuZXNfdmVydGV4LFxuXHRjb2xvcl9mcmFnbWVudDogY29sb3JfZnJhZ21lbnQsXG5cdGNvbG9yX3BhcnNfZnJhZ21lbnQ6IGNvbG9yX3BhcnNfZnJhZ21lbnQsXG5cdGNvbG9yX3BhcnNfdmVydGV4OiBjb2xvcl9wYXJzX3ZlcnRleCxcblx0Y29sb3JfdmVydGV4OiBjb2xvcl92ZXJ0ZXgsXG5cdGNvbW1vbjogY29tbW9uLFxuXHRjdWJlX3V2X3JlZmxlY3Rpb25fZnJhZ21lbnQ6IGN1YmVfdXZfcmVmbGVjdGlvbl9mcmFnbWVudCxcblx0ZGVmYXVsdG5vcm1hbF92ZXJ0ZXg6IGRlZmF1bHRub3JtYWxfdmVydGV4LFxuXHRkaXNwbGFjZW1lbnRtYXBfcGFyc192ZXJ0ZXg6IGRpc3BsYWNlbWVudG1hcF9wYXJzX3ZlcnRleCxcblx0ZGlzcGxhY2VtZW50bWFwX3ZlcnRleDogZGlzcGxhY2VtZW50bWFwX3ZlcnRleCxcblx0ZW1pc3NpdmVtYXBfZnJhZ21lbnQ6IGVtaXNzaXZlbWFwX2ZyYWdtZW50LFxuXHRlbWlzc2l2ZW1hcF9wYXJzX2ZyYWdtZW50OiBlbWlzc2l2ZW1hcF9wYXJzX2ZyYWdtZW50LFxuXHRlbmNvZGluZ3NfZnJhZ21lbnQ6IGVuY29kaW5nc19mcmFnbWVudCxcblx0ZW5jb2RpbmdzX3BhcnNfZnJhZ21lbnQ6IGVuY29kaW5nc19wYXJzX2ZyYWdtZW50LFxuXHRlbnZtYXBfZnJhZ21lbnQ6IGVudm1hcF9mcmFnbWVudCxcblx0ZW52bWFwX3BhcnNfZnJhZ21lbnQ6IGVudm1hcF9wYXJzX2ZyYWdtZW50LFxuXHRlbnZtYXBfcGFyc192ZXJ0ZXg6IGVudm1hcF9wYXJzX3ZlcnRleCxcblx0ZW52bWFwX3ZlcnRleDogZW52bWFwX3ZlcnRleCxcblx0Zm9nX3ZlcnRleDogZm9nX3ZlcnRleCxcblx0Zm9nX3BhcnNfdmVydGV4OiBmb2dfcGFyc192ZXJ0ZXgsXG5cdGZvZ19mcmFnbWVudDogZm9nX2ZyYWdtZW50LFxuXHRmb2dfcGFyc19mcmFnbWVudDogZm9nX3BhcnNfZnJhZ21lbnQsXG5cdGdyYWRpZW50bWFwX3BhcnNfZnJhZ21lbnQ6IGdyYWRpZW50bWFwX3BhcnNfZnJhZ21lbnQsXG5cdGxpZ2h0bWFwX2ZyYWdtZW50OiBsaWdodG1hcF9mcmFnbWVudCxcblx0bGlnaHRtYXBfcGFyc19mcmFnbWVudDogbGlnaHRtYXBfcGFyc19mcmFnbWVudCxcblx0bGlnaHRzX2xhbWJlcnRfdmVydGV4OiBsaWdodHNfbGFtYmVydF92ZXJ0ZXgsXG5cdGxpZ2h0c19wYXJzOiBsaWdodHNfcGFycyxcblx0bGlnaHRzX3Bob25nX2ZyYWdtZW50OiBsaWdodHNfcGhvbmdfZnJhZ21lbnQsXG5cdGxpZ2h0c19waG9uZ19wYXJzX2ZyYWdtZW50OiBsaWdodHNfcGhvbmdfcGFyc19mcmFnbWVudCxcblx0bGlnaHRzX3BoeXNpY2FsX2ZyYWdtZW50OiBsaWdodHNfcGh5c2ljYWxfZnJhZ21lbnQsXG5cdGxpZ2h0c19waHlzaWNhbF9wYXJzX2ZyYWdtZW50OiBsaWdodHNfcGh5c2ljYWxfcGFyc19mcmFnbWVudCxcblx0bGlnaHRzX3RlbXBsYXRlOiBsaWdodHNfdGVtcGxhdGUsXG5cdGxvZ2RlcHRoYnVmX2ZyYWdtZW50OiBsb2dkZXB0aGJ1Zl9mcmFnbWVudCxcblx0bG9nZGVwdGhidWZfcGFyc19mcmFnbWVudDogbG9nZGVwdGhidWZfcGFyc19mcmFnbWVudCxcblx0bG9nZGVwdGhidWZfcGFyc192ZXJ0ZXg6IGxvZ2RlcHRoYnVmX3BhcnNfdmVydGV4LFxuXHRsb2dkZXB0aGJ1Zl92ZXJ0ZXg6IGxvZ2RlcHRoYnVmX3ZlcnRleCxcblx0bWFwX2ZyYWdtZW50OiBtYXBfZnJhZ21lbnQsXG5cdG1hcF9wYXJzX2ZyYWdtZW50OiBtYXBfcGFyc19mcmFnbWVudCxcblx0bWFwX3BhcnRpY2xlX2ZyYWdtZW50OiBtYXBfcGFydGljbGVfZnJhZ21lbnQsXG5cdG1hcF9wYXJ0aWNsZV9wYXJzX2ZyYWdtZW50OiBtYXBfcGFydGljbGVfcGFyc19mcmFnbWVudCxcblx0bWV0YWxuZXNzbWFwX2ZyYWdtZW50OiBtZXRhbG5lc3NtYXBfZnJhZ21lbnQsXG5cdG1ldGFsbmVzc21hcF9wYXJzX2ZyYWdtZW50OiBtZXRhbG5lc3NtYXBfcGFyc19mcmFnbWVudCxcblx0bW9ycGhub3JtYWxfdmVydGV4OiBtb3JwaG5vcm1hbF92ZXJ0ZXgsXG5cdG1vcnBodGFyZ2V0X3BhcnNfdmVydGV4OiBtb3JwaHRhcmdldF9wYXJzX3ZlcnRleCxcblx0bW9ycGh0YXJnZXRfdmVydGV4OiBtb3JwaHRhcmdldF92ZXJ0ZXgsXG5cdG5vcm1hbF9mbGlwOiBub3JtYWxfZmxpcCxcblx0bm9ybWFsX2ZyYWdtZW50OiBub3JtYWxfZnJhZ21lbnQsXG5cdG5vcm1hbG1hcF9wYXJzX2ZyYWdtZW50OiBub3JtYWxtYXBfcGFyc19mcmFnbWVudCxcblx0cGFja2luZzogcGFja2luZyxcblx0cHJlbXVsdGlwbGllZF9hbHBoYV9mcmFnbWVudDogcHJlbXVsdGlwbGllZF9hbHBoYV9mcmFnbWVudCxcblx0cHJvamVjdF92ZXJ0ZXg6IHByb2plY3RfdmVydGV4LFxuXHRkaXRoZXJpbmdfZnJhZ21lbnQ6IGRpdGhlcmluZ19mcmFnbWVudCxcblx0ZGl0aGVyaW5nX3BhcnNfZnJhZ21lbnQ6IGRpdGhlcmluZ19wYXJzX2ZyYWdtZW50LFxuXHRyb3VnaG5lc3NtYXBfZnJhZ21lbnQ6IHJvdWdobmVzc21hcF9mcmFnbWVudCxcblx0cm91Z2huZXNzbWFwX3BhcnNfZnJhZ21lbnQ6IHJvdWdobmVzc21hcF9wYXJzX2ZyYWdtZW50LFxuXHRzaGFkb3dtYXBfcGFyc19mcmFnbWVudDogc2hhZG93bWFwX3BhcnNfZnJhZ21lbnQsXG5cdHNoYWRvd21hcF9wYXJzX3ZlcnRleDogc2hhZG93bWFwX3BhcnNfdmVydGV4LFxuXHRzaGFkb3dtYXBfdmVydGV4OiBzaGFkb3dtYXBfdmVydGV4LFxuXHRzaGFkb3dtYXNrX3BhcnNfZnJhZ21lbnQ6IHNoYWRvd21hc2tfcGFyc19mcmFnbWVudCxcblx0c2tpbmJhc2VfdmVydGV4OiBza2luYmFzZV92ZXJ0ZXgsXG5cdHNraW5uaW5nX3BhcnNfdmVydGV4OiBza2lubmluZ19wYXJzX3ZlcnRleCxcblx0c2tpbm5pbmdfdmVydGV4OiBza2lubmluZ192ZXJ0ZXgsXG5cdHNraW5ub3JtYWxfdmVydGV4OiBza2lubm9ybWFsX3ZlcnRleCxcblx0c3BlY3VsYXJtYXBfZnJhZ21lbnQ6IHNwZWN1bGFybWFwX2ZyYWdtZW50LFxuXHRzcGVjdWxhcm1hcF9wYXJzX2ZyYWdtZW50OiBzcGVjdWxhcm1hcF9wYXJzX2ZyYWdtZW50LFxuXHR0b25lbWFwcGluZ19mcmFnbWVudDogdG9uZW1hcHBpbmdfZnJhZ21lbnQsXG5cdHRvbmVtYXBwaW5nX3BhcnNfZnJhZ21lbnQ6IHRvbmVtYXBwaW5nX3BhcnNfZnJhZ21lbnQsXG5cdHV2X3BhcnNfZnJhZ21lbnQ6IHV2X3BhcnNfZnJhZ21lbnQsXG5cdHV2X3BhcnNfdmVydGV4OiB1dl9wYXJzX3ZlcnRleCxcblx0dXZfdmVydGV4OiB1dl92ZXJ0ZXgsXG5cdHV2Ml9wYXJzX2ZyYWdtZW50OiB1djJfcGFyc19mcmFnbWVudCxcblx0dXYyX3BhcnNfdmVydGV4OiB1djJfcGFyc192ZXJ0ZXgsXG5cdHV2Ml92ZXJ0ZXg6IHV2Ml92ZXJ0ZXgsXG5cdHdvcmxkcG9zX3ZlcnRleDogd29ybGRwb3NfdmVydGV4LFxuXG5cdGN1YmVfZnJhZzogY3ViZV9mcmFnLFxuXHRjdWJlX3ZlcnQ6IGN1YmVfdmVydCxcblx0ZGVwdGhfZnJhZzogZGVwdGhfZnJhZyxcblx0ZGVwdGhfdmVydDogZGVwdGhfdmVydCxcblx0ZGlzdGFuY2VSR0JBX2ZyYWc6IGRpc3RhbmNlUkdCQV9mcmFnLFxuXHRkaXN0YW5jZVJHQkFfdmVydDogZGlzdGFuY2VSR0JBX3ZlcnQsXG5cdGVxdWlyZWN0X2ZyYWc6IGVxdWlyZWN0X2ZyYWcsXG5cdGVxdWlyZWN0X3ZlcnQ6IGVxdWlyZWN0X3ZlcnQsXG5cdGxpbmVkYXNoZWRfZnJhZzogbGluZWRhc2hlZF9mcmFnLFxuXHRsaW5lZGFzaGVkX3ZlcnQ6IGxpbmVkYXNoZWRfdmVydCxcblx0bWVzaGJhc2ljX2ZyYWc6IG1lc2hiYXNpY19mcmFnLFxuXHRtZXNoYmFzaWNfdmVydDogbWVzaGJhc2ljX3ZlcnQsXG5cdG1lc2hsYW1iZXJ0X2ZyYWc6IG1lc2hsYW1iZXJ0X2ZyYWcsXG5cdG1lc2hsYW1iZXJ0X3ZlcnQ6IG1lc2hsYW1iZXJ0X3ZlcnQsXG5cdG1lc2hwaG9uZ19mcmFnOiBtZXNocGhvbmdfZnJhZyxcblx0bWVzaHBob25nX3ZlcnQ6IG1lc2hwaG9uZ192ZXJ0LFxuXHRtZXNocGh5c2ljYWxfZnJhZzogbWVzaHBoeXNpY2FsX2ZyYWcsXG5cdG1lc2hwaHlzaWNhbF92ZXJ0OiBtZXNocGh5c2ljYWxfdmVydCxcblx0bm9ybWFsX2ZyYWc6IG5vcm1hbF9mcmFnLFxuXHRub3JtYWxfdmVydDogbm9ybWFsX3ZlcnQsXG5cdHBvaW50c19mcmFnOiBwb2ludHNfZnJhZyxcblx0cG9pbnRzX3ZlcnQ6IHBvaW50c192ZXJ0LFxuXHRzaGFkb3dfZnJhZzogc2hhZG93X2ZyYWcsXG5cdHNoYWRvd192ZXJ0OiBzaGFkb3dfdmVydFxufTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgbWlrYWVsIGVtdGluZ2VyIC8gaHR0cDovL2dvbW8uc2UvXG4gKi9cblxudmFyIFNoYWRlckxpYiA9IHtcblxuXHRiYXNpYzoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmNvbW1vbixcblx0XHRcdFVuaWZvcm1zTGliLmFvbWFwLFxuXHRcdFx0VW5pZm9ybXNMaWIubGlnaHRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5mb2dcblx0XHRdICksXG5cblx0XHR2ZXJ0ZXhTaGFkZXI6IFNoYWRlckNodW5rLm1lc2hiYXNpY192ZXJ0LFxuXHRcdGZyYWdtZW50U2hhZGVyOiBTaGFkZXJDaHVuay5tZXNoYmFzaWNfZnJhZ1xuXG5cdH0sXG5cblx0bGFtYmVydDoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmNvbW1vbixcblx0XHRcdFVuaWZvcm1zTGliLmFvbWFwLFxuXHRcdFx0VW5pZm9ybXNMaWIubGlnaHRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5lbWlzc2l2ZW1hcCxcblx0XHRcdFVuaWZvcm1zTGliLmZvZyxcblx0XHRcdFVuaWZvcm1zTGliLmxpZ2h0cyxcblx0XHRcdHtcblx0XHRcdFx0ZW1pc3NpdmU6IHsgdmFsdWU6IG5ldyBDb2xvciggMHgwMDAwMDAgKSB9XG5cdFx0XHR9XG5cdFx0XSApLFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5tZXNobGFtYmVydF92ZXJ0LFxuXHRcdGZyYWdtZW50U2hhZGVyOiBTaGFkZXJDaHVuay5tZXNobGFtYmVydF9mcmFnXG5cblx0fSxcblxuXHRwaG9uZzoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmNvbW1vbixcblx0XHRcdFVuaWZvcm1zTGliLmFvbWFwLFxuXHRcdFx0VW5pZm9ybXNMaWIubGlnaHRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5lbWlzc2l2ZW1hcCxcblx0XHRcdFVuaWZvcm1zTGliLmJ1bXBtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5ub3JtYWxtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5kaXNwbGFjZW1lbnRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5ncmFkaWVudG1hcCxcblx0XHRcdFVuaWZvcm1zTGliLmZvZyxcblx0XHRcdFVuaWZvcm1zTGliLmxpZ2h0cyxcblx0XHRcdHtcblx0XHRcdFx0ZW1pc3NpdmU6IHsgdmFsdWU6IG5ldyBDb2xvciggMHgwMDAwMDAgKSB9LFxuXHRcdFx0XHRzcGVjdWxhcjogeyB2YWx1ZTogbmV3IENvbG9yKCAweDExMTExMSApIH0sXG5cdFx0XHRcdHNoaW5pbmVzczogeyB2YWx1ZTogMzAgfVxuXHRcdFx0fVxuXHRcdF0gKSxcblxuXHRcdHZlcnRleFNoYWRlcjogU2hhZGVyQ2h1bmsubWVzaHBob25nX3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLm1lc2hwaG9uZ19mcmFnXG5cblx0fSxcblxuXHRzdGFuZGFyZDoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmNvbW1vbixcblx0XHRcdFVuaWZvcm1zTGliLmFvbWFwLFxuXHRcdFx0VW5pZm9ybXNMaWIubGlnaHRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5lbWlzc2l2ZW1hcCxcblx0XHRcdFVuaWZvcm1zTGliLmJ1bXBtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5ub3JtYWxtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5kaXNwbGFjZW1lbnRtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5yb3VnaG5lc3NtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5tZXRhbG5lc3NtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5mb2csXG5cdFx0XHRVbmlmb3Jtc0xpYi5saWdodHMsXG5cdFx0XHR7XG5cdFx0XHRcdGVtaXNzaXZlOiB7IHZhbHVlOiBuZXcgQ29sb3IoIDB4MDAwMDAwICkgfSxcblx0XHRcdFx0cm91Z2huZXNzOiB7IHZhbHVlOiAwLjUgfSxcblx0XHRcdFx0bWV0YWxuZXNzOiB7IHZhbHVlOiAwLjUgfSxcblx0XHRcdFx0ZW52TWFwSW50ZW5zaXR5OiB7IHZhbHVlOiAxIH0gLy8gdGVtcG9yYXJ5XG5cdFx0XHR9XG5cdFx0XSApLFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5tZXNocGh5c2ljYWxfdmVydCxcblx0XHRmcmFnbWVudFNoYWRlcjogU2hhZGVyQ2h1bmsubWVzaHBoeXNpY2FsX2ZyYWdcblxuXHR9LFxuXG5cdHBvaW50czoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLnBvaW50cyxcblx0XHRcdFVuaWZvcm1zTGliLmZvZ1xuXHRcdF0gKSxcblxuXHRcdHZlcnRleFNoYWRlcjogU2hhZGVyQ2h1bmsucG9pbnRzX3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLnBvaW50c19mcmFnXG5cblx0fSxcblxuXHRkYXNoZWQ6IHtcblxuXHRcdHVuaWZvcm1zOiBVbmlmb3Jtc1V0aWxzLm1lcmdlKCBbXG5cdFx0XHRVbmlmb3Jtc0xpYi5jb21tb24sXG5cdFx0XHRVbmlmb3Jtc0xpYi5mb2csXG5cdFx0XHR7XG5cdFx0XHRcdHNjYWxlOiB7IHZhbHVlOiAxIH0sXG5cdFx0XHRcdGRhc2hTaXplOiB7IHZhbHVlOiAxIH0sXG5cdFx0XHRcdHRvdGFsU2l6ZTogeyB2YWx1ZTogMiB9XG5cdFx0XHR9XG5cdFx0XSApLFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5saW5lZGFzaGVkX3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLmxpbmVkYXNoZWRfZnJhZ1xuXG5cdH0sXG5cblx0ZGVwdGg6IHtcblxuXHRcdHVuaWZvcm1zOiBVbmlmb3Jtc1V0aWxzLm1lcmdlKCBbXG5cdFx0XHRVbmlmb3Jtc0xpYi5jb21tb24sXG5cdFx0XHRVbmlmb3Jtc0xpYi5kaXNwbGFjZW1lbnRtYXBcblx0XHRdICksXG5cblx0XHR2ZXJ0ZXhTaGFkZXI6IFNoYWRlckNodW5rLmRlcHRoX3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLmRlcHRoX2ZyYWdcblxuXHR9LFxuXG5cdG5vcm1hbDoge1xuXG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmNvbW1vbixcblx0XHRcdFVuaWZvcm1zTGliLmJ1bXBtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5ub3JtYWxtYXAsXG5cdFx0XHRVbmlmb3Jtc0xpYi5kaXNwbGFjZW1lbnRtYXAsXG5cdFx0XHR7XG5cdFx0XHRcdG9wYWNpdHk6IHsgdmFsdWU6IDEuMCB9XG5cdFx0XHR9XG5cdFx0XSApLFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5ub3JtYWxfdmVydCxcblx0XHRmcmFnbWVudFNoYWRlcjogU2hhZGVyQ2h1bmsubm9ybWFsX2ZyYWdcblxuXHR9LFxuXG5cdC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly9cdEN1YmUgbWFwIHNoYWRlclxuXHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdGN1YmU6IHtcblxuXHRcdHVuaWZvcm1zOiB7XG5cdFx0XHR0Q3ViZTogeyB2YWx1ZTogbnVsbCB9LFxuXHRcdFx0dEZsaXA6IHsgdmFsdWU6IC0gMSB9LFxuXHRcdFx0b3BhY2l0eTogeyB2YWx1ZTogMS4wIH1cblx0XHR9LFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5jdWJlX3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLmN1YmVfZnJhZ1xuXG5cdH0sXG5cblx0LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvL1x0Q3ViZSBtYXAgc2hhZGVyXG5cdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0ZXF1aXJlY3Q6IHtcblxuXHRcdHVuaWZvcm1zOiB7XG5cdFx0XHR0RXF1aXJlY3Q6IHsgdmFsdWU6IG51bGwgfSxcblx0XHRcdHRGbGlwOiB7IHZhbHVlOiAtIDEgfVxuXHRcdH0sXG5cblx0XHR2ZXJ0ZXhTaGFkZXI6IFNoYWRlckNodW5rLmVxdWlyZWN0X3ZlcnQsXG5cdFx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLmVxdWlyZWN0X2ZyYWdcblxuXHR9LFxuXG5cdGRpc3RhbmNlUkdCQToge1xuXG5cdFx0dW5pZm9ybXM6IHtcblx0XHRcdGxpZ2h0UG9zOiB7IHZhbHVlOiBuZXcgVmVjdG9yMygpIH1cblx0XHR9LFxuXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5kaXN0YW5jZVJHQkFfdmVydCxcblx0XHRmcmFnbWVudFNoYWRlcjogU2hhZGVyQ2h1bmsuZGlzdGFuY2VSR0JBX2ZyYWdcblxuXHR9XG5cbn07XG5cblNoYWRlckxpYi5waHlzaWNhbCA9IHtcblxuXHR1bmlmb3JtczogVW5pZm9ybXNVdGlscy5tZXJnZSggW1xuXHRcdFNoYWRlckxpYi5zdGFuZGFyZC51bmlmb3Jtcyxcblx0XHR7XG5cdFx0XHRjbGVhckNvYXQ6IHsgdmFsdWU6IDAgfSxcblx0XHRcdGNsZWFyQ29hdFJvdWdobmVzczogeyB2YWx1ZTogMCB9XG5cdFx0fVxuXHRdICksXG5cblx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVuay5tZXNocGh5c2ljYWxfdmVydCxcblx0ZnJhZ21lbnRTaGFkZXI6IFNoYWRlckNodW5rLm1lc2hwaHlzaWNhbF9mcmFnXG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICovXG5cbmZ1bmN0aW9uIEJveDIoIG1pbiwgbWF4ICkge1xuXG5cdHRoaXMubWluID0gKCBtaW4gIT09IHVuZGVmaW5lZCApID8gbWluIDogbmV3IFZlY3RvcjIoICsgSW5maW5pdHksICsgSW5maW5pdHkgKTtcblx0dGhpcy5tYXggPSAoIG1heCAhPT0gdW5kZWZpbmVkICkgPyBtYXggOiBuZXcgVmVjdG9yMiggLSBJbmZpbml0eSwgLSBJbmZpbml0eSApO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEJveDIucHJvdG90eXBlLCB7XG5cblx0c2V0OiBmdW5jdGlvbiAoIG1pbiwgbWF4ICkge1xuXG5cdFx0dGhpcy5taW4uY29weSggbWluICk7XG5cdFx0dGhpcy5tYXguY29weSggbWF4ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21Qb2ludHM6IGZ1bmN0aW9uICggcG9pbnRzICkge1xuXG5cdFx0dGhpcy5tYWtlRW1wdHkoKTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSBwb2ludHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHRoaXMuZXhwYW5kQnlQb2ludCggcG9pbnRzWyBpIF0gKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbUNlbnRlckFuZFNpemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IyKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gc2V0RnJvbUNlbnRlckFuZFNpemUoIGNlbnRlciwgc2l6ZSApIHtcblxuXHRcdFx0dmFyIGhhbGZTaXplID0gdjEuY29weSggc2l6ZSApLm11bHRpcGx5U2NhbGFyKCAwLjUgKTtcblx0XHRcdHRoaXMubWluLmNvcHkoIGNlbnRlciApLnN1YiggaGFsZlNpemUgKTtcblx0XHRcdHRoaXMubWF4LmNvcHkoIGNlbnRlciApLmFkZCggaGFsZlNpemUgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHR0aGlzLm1pbi5jb3B5KCBib3gubWluICk7XG5cdFx0dGhpcy5tYXguY29weSggYm94Lm1heCApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRtYWtlRW1wdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMubWluLnggPSB0aGlzLm1pbi55ID0gKyBJbmZpbml0eTtcblx0XHR0aGlzLm1heC54ID0gdGhpcy5tYXgueSA9IC0gSW5maW5pdHk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGlzRW1wdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIHRoaXMgaXMgYSBtb3JlIHJvYnVzdCBjaGVjayBmb3IgZW1wdHkgdGhhbiAoIHZvbHVtZSA8PSAwICkgYmVjYXVzZSB2b2x1bWUgY2FuIGdldCBwb3NpdGl2ZSB3aXRoIHR3byBuZWdhdGl2ZSBheGVzXG5cblx0XHRyZXR1cm4gKCB0aGlzLm1heC54IDwgdGhpcy5taW4ueCApIHx8ICggdGhpcy5tYXgueSA8IHRoaXMubWluLnkgKTtcblxuXHR9LFxuXG5cdGdldENlbnRlcjogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMigpO1xuXHRcdHJldHVybiB0aGlzLmlzRW1wdHkoKSA/IHJlc3VsdC5zZXQoIDAsIDAgKSA6IHJlc3VsdC5hZGRWZWN0b3JzKCB0aGlzLm1pbiwgdGhpcy5tYXggKS5tdWx0aXBseVNjYWxhciggMC41ICk7XG5cblx0fSxcblxuXHRnZXRTaXplOiBmdW5jdGlvbiAoIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IyKCk7XG5cdFx0cmV0dXJuIHRoaXMuaXNFbXB0eSgpID8gcmVzdWx0LnNldCggMCwgMCApIDogcmVzdWx0LnN1YlZlY3RvcnMoIHRoaXMubWF4LCB0aGlzLm1pbiApO1xuXG5cdH0sXG5cblx0ZXhwYW5kQnlQb2ludDogZnVuY3Rpb24gKCBwb2ludCApIHtcblxuXHRcdHRoaXMubWluLm1pbiggcG9pbnQgKTtcblx0XHR0aGlzLm1heC5tYXgoIHBvaW50ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGV4cGFuZEJ5VmVjdG9yOiBmdW5jdGlvbiAoIHZlY3RvciApIHtcblxuXHRcdHRoaXMubWluLnN1YiggdmVjdG9yICk7XG5cdFx0dGhpcy5tYXguYWRkKCB2ZWN0b3IgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXhwYW5kQnlTY2FsYXI6IGZ1bmN0aW9uICggc2NhbGFyICkge1xuXG5cdFx0dGhpcy5taW4uYWRkU2NhbGFyKCAtIHNjYWxhciApO1xuXHRcdHRoaXMubWF4LmFkZFNjYWxhciggc2NhbGFyICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvbnRhaW5zUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQgKSB7XG5cblx0XHRyZXR1cm4gcG9pbnQueCA8IHRoaXMubWluLnggfHwgcG9pbnQueCA+IHRoaXMubWF4LnggfHxcblx0XHRcdHBvaW50LnkgPCB0aGlzLm1pbi55IHx8IHBvaW50LnkgPiB0aGlzLm1heC55ID8gZmFsc2UgOiB0cnVlO1xuXG5cdH0sXG5cblx0Y29udGFpbnNCb3g6IGZ1bmN0aW9uICggYm94ICkge1xuXG5cdFx0cmV0dXJuIHRoaXMubWluLnggPD0gYm94Lm1pbi54ICYmIGJveC5tYXgueCA8PSB0aGlzLm1heC54ICYmXG5cdFx0XHR0aGlzLm1pbi55IDw9IGJveC5taW4ueSAmJiBib3gubWF4LnkgPD0gdGhpcy5tYXgueTtcblxuXHR9LFxuXG5cdGdldFBhcmFtZXRlcjogZnVuY3Rpb24gKCBwb2ludCwgb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHQvLyBUaGlzIGNhbiBwb3RlbnRpYWxseSBoYXZlIGEgZGl2aWRlIGJ5IHplcm8gaWYgdGhlIGJveFxuXHRcdC8vIGhhcyBhIHNpemUgZGltZW5zaW9uIG9mIDAuXG5cblx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjIoKTtcblxuXHRcdHJldHVybiByZXN1bHQuc2V0KFxuXHRcdFx0KCBwb2ludC54IC0gdGhpcy5taW4ueCApIC8gKCB0aGlzLm1heC54IC0gdGhpcy5taW4ueCApLFxuXHRcdFx0KCBwb2ludC55IC0gdGhpcy5taW4ueSApIC8gKCB0aGlzLm1heC55IC0gdGhpcy5taW4ueSApXG5cdFx0KTtcblxuXHR9LFxuXG5cdGludGVyc2VjdHNCb3g6IGZ1bmN0aW9uICggYm94ICkge1xuXG5cdFx0Ly8gdXNpbmcgNCBzcGxpdHRpbmcgcGxhbmVzIHRvIHJ1bGUgb3V0IGludGVyc2VjdGlvbnNcblxuXHRcdHJldHVybiBib3gubWF4LnggPCB0aGlzLm1pbi54IHx8IGJveC5taW4ueCA+IHRoaXMubWF4LnggfHxcblx0XHRcdGJveC5tYXgueSA8IHRoaXMubWluLnkgfHwgYm94Lm1pbi55ID4gdGhpcy5tYXgueSA/IGZhbHNlIDogdHJ1ZTtcblxuXHR9LFxuXG5cdGNsYW1wUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IyKCk7XG5cdFx0cmV0dXJuIHJlc3VsdC5jb3B5KCBwb2ludCApLmNsYW1wKCB0aGlzLm1pbiwgdGhpcy5tYXggKTtcblxuXHR9LFxuXG5cdGRpc3RhbmNlVG9Qb2ludDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjIoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBkaXN0YW5jZVRvUG9pbnQoIHBvaW50ICkge1xuXG5cdFx0XHR2YXIgY2xhbXBlZFBvaW50ID0gdjEuY29weSggcG9pbnQgKS5jbGFtcCggdGhpcy5taW4sIHRoaXMubWF4ICk7XG5cdFx0XHRyZXR1cm4gY2xhbXBlZFBvaW50LnN1YiggcG9pbnQgKS5sZW5ndGgoKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGludGVyc2VjdDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHR0aGlzLm1pbi5tYXgoIGJveC5taW4gKTtcblx0XHR0aGlzLm1heC5taW4oIGJveC5tYXggKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0dW5pb246IGZ1bmN0aW9uICggYm94ICkge1xuXG5cdFx0dGhpcy5taW4ubWluKCBib3gubWluICk7XG5cdFx0dGhpcy5tYXgubWF4KCBib3gubWF4ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRyYW5zbGF0ZTogZnVuY3Rpb24gKCBvZmZzZXQgKSB7XG5cblx0XHR0aGlzLm1pbi5hZGQoIG9mZnNldCApO1xuXHRcdHRoaXMubWF4LmFkZCggb2Zmc2V0ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGVxdWFsczogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHRyZXR1cm4gYm94Lm1pbi5lcXVhbHMoIHRoaXMubWluICkgJiYgYm94Lm1heC5lcXVhbHMoIHRoaXMubWF4ICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gTGVuc0ZsYXJlUGx1Z2luKCByZW5kZXJlciwgZmxhcmVzICkge1xuXG5cdHZhciBnbCA9IHJlbmRlcmVyLmNvbnRleHQ7XG5cdHZhciBzdGF0ZSA9IHJlbmRlcmVyLnN0YXRlO1xuXG5cdHZhciB2ZXJ0ZXhCdWZmZXIsIGVsZW1lbnRCdWZmZXI7XG5cdHZhciBzaGFkZXIsIHByb2dyYW0sIGF0dHJpYnV0ZXMsIHVuaWZvcm1zO1xuXG5cdHZhciB0ZW1wVGV4dHVyZSwgb2NjbHVzaW9uVGV4dHVyZTtcblxuXHRmdW5jdGlvbiBpbml0KCkge1xuXG5cdFx0dmFyIHZlcnRpY2VzID0gbmV3IEZsb2F0MzJBcnJheSggW1xuXHRcdFx0LSAxLCAtIDEsICAwLCAwLFxuXHRcdFx0IDEsIC0gMSwgIDEsIDAsXG5cdFx0XHQgMSwgIDEsICAxLCAxLFxuXHRcdFx0LSAxLCAgMSwgIDAsIDFcblx0XHRdICk7XG5cblx0XHR2YXIgZmFjZXMgPSBuZXcgVWludDE2QXJyYXkoIFtcblx0XHRcdDAsIDEsIDIsXG5cdFx0XHQwLCAyLCAzXG5cdFx0XSApO1xuXG5cdFx0Ly8gYnVmZmVyc1xuXG5cdFx0dmVydGV4QnVmZmVyICAgICA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuXHRcdGVsZW1lbnRCdWZmZXIgICAgPSBnbC5jcmVhdGVCdWZmZXIoKTtcblxuXHRcdGdsLmJpbmRCdWZmZXIoIGdsLkFSUkFZX0JVRkZFUiwgdmVydGV4QnVmZmVyICk7XG5cdFx0Z2wuYnVmZmVyRGF0YSggZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0aWNlcywgZ2wuU1RBVElDX0RSQVcgKTtcblxuXHRcdGdsLmJpbmRCdWZmZXIoIGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBlbGVtZW50QnVmZmVyICk7XG5cdFx0Z2wuYnVmZmVyRGF0YSggZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGZhY2VzLCBnbC5TVEFUSUNfRFJBVyApO1xuXG5cdFx0Ly8gdGV4dHVyZXNcblxuXHRcdHRlbXBUZXh0dXJlICAgICAgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG5cdFx0b2NjbHVzaW9uVGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcblxuXHRcdHN0YXRlLmJpbmRUZXh0dXJlKCBnbC5URVhUVVJFXzJELCB0ZW1wVGV4dHVyZSApO1xuXHRcdGdsLnRleEltYWdlMkQoIGdsLlRFWFRVUkVfMkQsIDAsIGdsLlJHQiwgMTYsIDE2LCAwLCBnbC5SR0IsIGdsLlVOU0lHTkVEX0JZVEUsIG51bGwgKTtcblx0XHRnbC50ZXhQYXJhbWV0ZXJpKCBnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfUywgZ2wuQ0xBTVBfVE9fRURHRSApO1xuXHRcdGdsLnRleFBhcmFtZXRlcmkoIGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFICk7XG5cdFx0Z2wudGV4UGFyYW1ldGVyaSggZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5ORUFSRVNUICk7XG5cdFx0Z2wudGV4UGFyYW1ldGVyaSggZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5ORUFSRVNUICk7XG5cblx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggZ2wuVEVYVFVSRV8yRCwgb2NjbHVzaW9uVGV4dHVyZSApO1xuXHRcdGdsLnRleEltYWdlMkQoIGdsLlRFWFRVUkVfMkQsIDAsIGdsLlJHQkEsIDE2LCAxNiwgMCwgZ2wuUkdCQSwgZ2wuVU5TSUdORURfQllURSwgbnVsbCApO1xuXHRcdGdsLnRleFBhcmFtZXRlcmkoIGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFICk7XG5cdFx0Z2wudGV4UGFyYW1ldGVyaSggZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UgKTtcblx0XHRnbC50ZXhQYXJhbWV0ZXJpKCBnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QgKTtcblx0XHRnbC50ZXhQYXJhbWV0ZXJpKCBnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QgKTtcblxuXHRcdHNoYWRlciA9IHtcblxuXHRcdFx0dmVydGV4U2hhZGVyOiBbXG5cblx0XHRcdFx0XCJ1bmlmb3JtIGxvd3AgaW50IHJlbmRlclR5cGU7XCIsXG5cblx0XHRcdFx0XCJ1bmlmb3JtIHZlYzMgc2NyZWVuUG9zaXRpb247XCIsXG5cdFx0XHRcdFwidW5pZm9ybSB2ZWMyIHNjYWxlO1wiLFxuXHRcdFx0XHRcInVuaWZvcm0gZmxvYXQgcm90YXRpb247XCIsXG5cblx0XHRcdFx0XCJ1bmlmb3JtIHNhbXBsZXIyRCBvY2NsdXNpb25NYXA7XCIsXG5cblx0XHRcdFx0XCJhdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjtcIixcblx0XHRcdFx0XCJhdHRyaWJ1dGUgdmVjMiB1djtcIixcblxuXHRcdFx0XHRcInZhcnlpbmcgdmVjMiB2VVY7XCIsXG5cdFx0XHRcdFwidmFyeWluZyBmbG9hdCB2VmlzaWJpbGl0eTtcIixcblxuXHRcdFx0XHRcInZvaWQgbWFpbigpIHtcIixcblxuXHRcdFx0XHRcdFwidlVWID0gdXY7XCIsXG5cblx0XHRcdFx0XHRcInZlYzIgcG9zID0gcG9zaXRpb247XCIsXG5cblx0XHRcdFx0XHRcImlmICggcmVuZGVyVHlwZSA9PSAyICkge1wiLFxuXG5cdFx0XHRcdFx0XHRcInZlYzQgdmlzaWJpbGl0eSA9IHRleHR1cmUyRCggb2NjbHVzaW9uTWFwLCB2ZWMyKCAwLjEsIDAuMSApICk7XCIsXG5cdFx0XHRcdFx0XHRcInZpc2liaWxpdHkgKz0gdGV4dHVyZTJEKCBvY2NsdXNpb25NYXAsIHZlYzIoIDAuNSwgMC4xICkgKTtcIixcblx0XHRcdFx0XHRcdFwidmlzaWJpbGl0eSArPSB0ZXh0dXJlMkQoIG9jY2x1c2lvbk1hcCwgdmVjMiggMC45LCAwLjEgKSApO1wiLFxuXHRcdFx0XHRcdFx0XCJ2aXNpYmlsaXR5ICs9IHRleHR1cmUyRCggb2NjbHVzaW9uTWFwLCB2ZWMyKCAwLjksIDAuNSApICk7XCIsXG5cdFx0XHRcdFx0XHRcInZpc2liaWxpdHkgKz0gdGV4dHVyZTJEKCBvY2NsdXNpb25NYXAsIHZlYzIoIDAuOSwgMC45ICkgKTtcIixcblx0XHRcdFx0XHRcdFwidmlzaWJpbGl0eSArPSB0ZXh0dXJlMkQoIG9jY2x1c2lvbk1hcCwgdmVjMiggMC41LCAwLjkgKSApO1wiLFxuXHRcdFx0XHRcdFx0XCJ2aXNpYmlsaXR5ICs9IHRleHR1cmUyRCggb2NjbHVzaW9uTWFwLCB2ZWMyKCAwLjEsIDAuOSApICk7XCIsXG5cdFx0XHRcdFx0XHRcInZpc2liaWxpdHkgKz0gdGV4dHVyZTJEKCBvY2NsdXNpb25NYXAsIHZlYzIoIDAuMSwgMC41ICkgKTtcIixcblx0XHRcdFx0XHRcdFwidmlzaWJpbGl0eSArPSB0ZXh0dXJlMkQoIG9jY2x1c2lvbk1hcCwgdmVjMiggMC41LCAwLjUgKSApO1wiLFxuXG5cdFx0XHRcdFx0XHRcInZWaXNpYmlsaXR5ID0gICAgICAgIHZpc2liaWxpdHkuciAvIDkuMDtcIixcblx0XHRcdFx0XHRcdFwidlZpc2liaWxpdHkgKj0gMS4wIC0gdmlzaWJpbGl0eS5nIC8gOS4wO1wiLFxuXHRcdFx0XHRcdFx0XCJ2VmlzaWJpbGl0eSAqPSAgICAgICB2aXNpYmlsaXR5LmIgLyA5LjA7XCIsXG5cdFx0XHRcdFx0XHRcInZWaXNpYmlsaXR5ICo9IDEuMCAtIHZpc2liaWxpdHkuYSAvIDkuMDtcIixcblxuXHRcdFx0XHRcdFx0XCJwb3MueCA9IGNvcyggcm90YXRpb24gKSAqIHBvc2l0aW9uLnggLSBzaW4oIHJvdGF0aW9uICkgKiBwb3NpdGlvbi55O1wiLFxuXHRcdFx0XHRcdFx0XCJwb3MueSA9IHNpbiggcm90YXRpb24gKSAqIHBvc2l0aW9uLnggKyBjb3MoIHJvdGF0aW9uICkgKiBwb3NpdGlvbi55O1wiLFxuXG5cdFx0XHRcdFx0XCJ9XCIsXG5cblx0XHRcdFx0XHRcImdsX1Bvc2l0aW9uID0gdmVjNCggKCBwb3MgKiBzY2FsZSArIHNjcmVlblBvc2l0aW9uLnh5ICkueHksIHNjcmVlblBvc2l0aW9uLnosIDEuMCApO1wiLFxuXG5cdFx0XHRcdFwifVwiXG5cblx0XHRcdF0uam9pbiggXCJcXG5cIiApLFxuXG5cdFx0XHRmcmFnbWVudFNoYWRlcjogW1xuXG5cdFx0XHRcdFwidW5pZm9ybSBsb3dwIGludCByZW5kZXJUeXBlO1wiLFxuXG5cdFx0XHRcdFwidW5pZm9ybSBzYW1wbGVyMkQgbWFwO1wiLFxuXHRcdFx0XHRcInVuaWZvcm0gZmxvYXQgb3BhY2l0eTtcIixcblx0XHRcdFx0XCJ1bmlmb3JtIHZlYzMgY29sb3I7XCIsXG5cblx0XHRcdFx0XCJ2YXJ5aW5nIHZlYzIgdlVWO1wiLFxuXHRcdFx0XHRcInZhcnlpbmcgZmxvYXQgdlZpc2liaWxpdHk7XCIsXG5cblx0XHRcdFx0XCJ2b2lkIG1haW4oKSB7XCIsXG5cblx0XHRcdFx0XHQvLyBwaW5rIHNxdWFyZVxuXG5cdFx0XHRcdFx0XCJpZiAoIHJlbmRlclR5cGUgPT0gMCApIHtcIixcblxuXHRcdFx0XHRcdFx0XCJnbF9GcmFnQ29sb3IgPSB2ZWM0KCAxLjAsIDAuMCwgMS4wLCAwLjAgKTtcIixcblxuXHRcdFx0XHRcdC8vIHJlc3RvcmVcblxuXHRcdFx0XHRcdFwifSBlbHNlIGlmICggcmVuZGVyVHlwZSA9PSAxICkge1wiLFxuXG5cdFx0XHRcdFx0XHRcImdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRCggbWFwLCB2VVYgKTtcIixcblxuXHRcdFx0XHRcdC8vIGZsYXJlXG5cblx0XHRcdFx0XHRcIn0gZWxzZSB7XCIsXG5cblx0XHRcdFx0XHRcdFwidmVjNCB0ZXh0dXJlID0gdGV4dHVyZTJEKCBtYXAsIHZVViApO1wiLFxuXHRcdFx0XHRcdFx0XCJ0ZXh0dXJlLmEgKj0gb3BhY2l0eSAqIHZWaXNpYmlsaXR5O1wiLFxuXHRcdFx0XHRcdFx0XCJnbF9GcmFnQ29sb3IgPSB0ZXh0dXJlO1wiLFxuXHRcdFx0XHRcdFx0XCJnbF9GcmFnQ29sb3IucmdiICo9IGNvbG9yO1wiLFxuXG5cdFx0XHRcdFx0XCJ9XCIsXG5cblx0XHRcdFx0XCJ9XCJcblxuXHRcdFx0XS5qb2luKCBcIlxcblwiIClcblxuXHRcdH07XG5cblx0XHRwcm9ncmFtID0gY3JlYXRlUHJvZ3JhbSggc2hhZGVyICk7XG5cblx0XHRhdHRyaWJ1dGVzID0ge1xuXHRcdFx0dmVydGV4OiBnbC5nZXRBdHRyaWJMb2NhdGlvbiAoIHByb2dyYW0sIFwicG9zaXRpb25cIiApLFxuXHRcdFx0dXY6ICAgICBnbC5nZXRBdHRyaWJMb2NhdGlvbiAoIHByb2dyYW0sIFwidXZcIiApXG5cdFx0fTtcblxuXHRcdHVuaWZvcm1zID0ge1xuXHRcdFx0cmVuZGVyVHlwZTogICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbiggcHJvZ3JhbSwgXCJyZW5kZXJUeXBlXCIgKSxcblx0XHRcdG1hcDogICAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sIFwibWFwXCIgKSxcblx0XHRcdG9jY2x1c2lvbk1hcDogICBnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sIFwib2NjbHVzaW9uTWFwXCIgKSxcblx0XHRcdG9wYWNpdHk6ICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sIFwib3BhY2l0eVwiICksXG5cdFx0XHRjb2xvcjogICAgICAgICAgZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCBcImNvbG9yXCIgKSxcblx0XHRcdHNjYWxlOiAgICAgICAgICBnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sIFwic2NhbGVcIiApLFxuXHRcdFx0cm90YXRpb246ICAgICAgIGdsLmdldFVuaWZvcm1Mb2NhdGlvbiggcHJvZ3JhbSwgXCJyb3RhdGlvblwiICksXG5cdFx0XHRzY3JlZW5Qb3NpdGlvbjogZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCBcInNjcmVlblBvc2l0aW9uXCIgKVxuXHRcdH07XG5cblx0fVxuXG5cdC8qXG5cdCAqIFJlbmRlciBsZW5zIGZsYXJlc1xuXHQgKiBNZXRob2Q6IHJlbmRlcnMgMTZ4MTYgMHhmZjAwZmYtY29sb3JlZCBwb2ludHMgc2NhdHRlcmVkIG92ZXIgdGhlIGxpZ2h0IHNvdXJjZSBhcmVhLFxuXHQgKiAgICAgICAgIHJlYWRzIHRoZXNlIGJhY2sgYW5kIGNhbGN1bGF0ZXMgb2NjbHVzaW9uLlxuXHQgKi9cblxuXHR0aGlzLnJlbmRlciA9IGZ1bmN0aW9uICggc2NlbmUsIGNhbWVyYSwgdmlld3BvcnQgKSB7XG5cblx0XHRpZiAoIGZsYXJlcy5sZW5ndGggPT09IDAgKSByZXR1cm47XG5cblx0XHR2YXIgdGVtcFBvc2l0aW9uID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHZhciBpbnZBc3BlY3QgPSB2aWV3cG9ydC53IC8gdmlld3BvcnQueixcblx0XHRcdGhhbGZWaWV3cG9ydFdpZHRoID0gdmlld3BvcnQueiAqIDAuNSxcblx0XHRcdGhhbGZWaWV3cG9ydEhlaWdodCA9IHZpZXdwb3J0LncgKiAwLjU7XG5cblx0XHR2YXIgc2l6ZSA9IDE2IC8gdmlld3BvcnQudyxcblx0XHRcdHNjYWxlID0gbmV3IFZlY3RvcjIoIHNpemUgKiBpbnZBc3BlY3QsIHNpemUgKTtcblxuXHRcdHZhciBzY3JlZW5Qb3NpdGlvbiA9IG5ldyBWZWN0b3IzKCAxLCAxLCAwICksXG5cdFx0XHRzY3JlZW5Qb3NpdGlvblBpeGVscyA9IG5ldyBWZWN0b3IyKCAxLCAxICk7XG5cblx0XHR2YXIgdmFsaWRBcmVhID0gbmV3IEJveDIoKTtcblxuXHRcdHZhbGlkQXJlYS5taW4uc2V0KCB2aWV3cG9ydC54LCB2aWV3cG9ydC55ICk7XG5cdFx0dmFsaWRBcmVhLm1heC5zZXQoIHZpZXdwb3J0LnggKyAoIHZpZXdwb3J0LnogLSAxNiApLCB2aWV3cG9ydC55ICsgKCB2aWV3cG9ydC53IC0gMTYgKSApO1xuXG5cdFx0aWYgKCBwcm9ncmFtID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGluaXQoKTtcblxuXHRcdH1cblxuXHRcdGdsLnVzZVByb2dyYW0oIHByb2dyYW0gKTtcblxuXHRcdHN0YXRlLmluaXRBdHRyaWJ1dGVzKCk7XG5cdFx0c3RhdGUuZW5hYmxlQXR0cmlidXRlKCBhdHRyaWJ1dGVzLnZlcnRleCApO1xuXHRcdHN0YXRlLmVuYWJsZUF0dHJpYnV0ZSggYXR0cmlidXRlcy51diApO1xuXHRcdHN0YXRlLmRpc2FibGVVbnVzZWRBdHRyaWJ1dGVzKCk7XG5cblx0XHQvLyBsb29wIHRocm91Z2ggYWxsIGxlbnMgZmxhcmVzIHRvIHVwZGF0ZSB0aGVpciBvY2NsdXNpb24gYW5kIHBvc2l0aW9uc1xuXHRcdC8vIHNldHVwIGdsIGFuZCBjb21tb24gdXNlZCBhdHRyaWJzL3VuaWZvcm1zXG5cblx0XHRnbC51bmlmb3JtMWkoIHVuaWZvcm1zLm9jY2x1c2lvbk1hcCwgMCApO1xuXHRcdGdsLnVuaWZvcm0xaSggdW5pZm9ybXMubWFwLCAxICk7XG5cblx0XHRnbC5iaW5kQnVmZmVyKCBnbC5BUlJBWV9CVUZGRVIsIHZlcnRleEJ1ZmZlciApO1xuXHRcdGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoIGF0dHJpYnV0ZXMudmVydGV4LCAyLCBnbC5GTE9BVCwgZmFsc2UsIDIgKiA4LCAwICk7XG5cdFx0Z2wudmVydGV4QXR0cmliUG9pbnRlciggYXR0cmlidXRlcy51diwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAyICogOCwgOCApO1xuXG5cdFx0Z2wuYmluZEJ1ZmZlciggZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGVsZW1lbnRCdWZmZXIgKTtcblxuXHRcdHN0YXRlLmRpc2FibGUoIGdsLkNVTExfRkFDRSApO1xuXHRcdHN0YXRlLmJ1ZmZlcnMuZGVwdGguc2V0TWFzayggZmFsc2UgKTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGZsYXJlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRzaXplID0gMTYgLyB2aWV3cG9ydC53O1xuXHRcdFx0c2NhbGUuc2V0KCBzaXplICogaW52QXNwZWN0LCBzaXplICk7XG5cblx0XHRcdC8vIGNhbGMgb2JqZWN0IHNjcmVlbiBwb3NpdGlvblxuXG5cdFx0XHR2YXIgZmxhcmUgPSBmbGFyZXNbIGkgXTtcblxuXHRcdFx0dGVtcFBvc2l0aW9uLnNldCggZmxhcmUubWF0cml4V29ybGQuZWxlbWVudHNbIDEyIF0sIGZsYXJlLm1hdHJpeFdvcmxkLmVsZW1lbnRzWyAxMyBdLCBmbGFyZS5tYXRyaXhXb3JsZC5lbGVtZW50c1sgMTQgXSApO1xuXG5cdFx0XHR0ZW1wUG9zaXRpb24uYXBwbHlNYXRyaXg0KCBjYW1lcmEubWF0cml4V29ybGRJbnZlcnNlICk7XG5cdFx0XHR0ZW1wUG9zaXRpb24uYXBwbHlNYXRyaXg0KCBjYW1lcmEucHJvamVjdGlvbk1hdHJpeCApO1xuXG5cdFx0XHQvLyBzZXR1cCBhcnJheXMgZm9yIGdsIHByb2dyYW1zXG5cblx0XHRcdHNjcmVlblBvc2l0aW9uLmNvcHkoIHRlbXBQb3NpdGlvbiApO1xuXG5cdFx0XHQvLyBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBjb29yZGluYXRlIG9mIHRoZSBsb3dlciBsZWZ0IGNvcm5lciBvZiB0aGUgcGl4ZWxzIHRvIGNvcHlcblxuXHRcdFx0c2NyZWVuUG9zaXRpb25QaXhlbHMueCA9IHZpZXdwb3J0LnggKyAoIHNjcmVlblBvc2l0aW9uLnggKiBoYWxmVmlld3BvcnRXaWR0aCApICsgaGFsZlZpZXdwb3J0V2lkdGggLSA4O1xuXHRcdFx0c2NyZWVuUG9zaXRpb25QaXhlbHMueSA9IHZpZXdwb3J0LnkgKyAoIHNjcmVlblBvc2l0aW9uLnkgKiBoYWxmVmlld3BvcnRIZWlnaHQgKSArIGhhbGZWaWV3cG9ydEhlaWdodCAtIDg7XG5cblx0XHRcdC8vIHNjcmVlbiBjdWxsXG5cblx0XHRcdGlmICggdmFsaWRBcmVhLmNvbnRhaW5zUG9pbnQoIHNjcmVlblBvc2l0aW9uUGl4ZWxzICkgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0Ly8gc2F2ZSBjdXJyZW50IFJHQiB0byB0ZW1wIHRleHR1cmVcblxuXHRcdFx0XHRzdGF0ZS5hY3RpdmVUZXh0dXJlKCBnbC5URVhUVVJFMCApO1xuXHRcdFx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggZ2wuVEVYVFVSRV8yRCwgbnVsbCApO1xuXHRcdFx0XHRzdGF0ZS5hY3RpdmVUZXh0dXJlKCBnbC5URVhUVVJFMSApO1xuXHRcdFx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggZ2wuVEVYVFVSRV8yRCwgdGVtcFRleHR1cmUgKTtcblx0XHRcdFx0Z2wuY29weVRleEltYWdlMkQoIGdsLlRFWFRVUkVfMkQsIDAsIGdsLlJHQiwgc2NyZWVuUG9zaXRpb25QaXhlbHMueCwgc2NyZWVuUG9zaXRpb25QaXhlbHMueSwgMTYsIDE2LCAwICk7XG5cblxuXHRcdFx0XHQvLyByZW5kZXIgcGluayBxdWFkXG5cblx0XHRcdFx0Z2wudW5pZm9ybTFpKCB1bmlmb3Jtcy5yZW5kZXJUeXBlLCAwICk7XG5cdFx0XHRcdGdsLnVuaWZvcm0yZiggdW5pZm9ybXMuc2NhbGUsIHNjYWxlLngsIHNjYWxlLnkgKTtcblx0XHRcdFx0Z2wudW5pZm9ybTNmKCB1bmlmb3Jtcy5zY3JlZW5Qb3NpdGlvbiwgc2NyZWVuUG9zaXRpb24ueCwgc2NyZWVuUG9zaXRpb24ueSwgc2NyZWVuUG9zaXRpb24ueiApO1xuXG5cdFx0XHRcdHN0YXRlLmRpc2FibGUoIGdsLkJMRU5EICk7XG5cdFx0XHRcdHN0YXRlLmVuYWJsZSggZ2wuREVQVEhfVEVTVCApO1xuXG5cdFx0XHRcdGdsLmRyYXdFbGVtZW50cyggZ2wuVFJJQU5HTEVTLCA2LCBnbC5VTlNJR05FRF9TSE9SVCwgMCApO1xuXG5cblx0XHRcdFx0Ly8gY29weSByZXN1bHQgdG8gb2NjbHVzaW9uTWFwXG5cblx0XHRcdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggZ2wuVEVYVFVSRTAgKTtcblx0XHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIGdsLlRFWFRVUkVfMkQsIG9jY2x1c2lvblRleHR1cmUgKTtcblx0XHRcdFx0Z2wuY29weVRleEltYWdlMkQoIGdsLlRFWFRVUkVfMkQsIDAsIGdsLlJHQkEsIHNjcmVlblBvc2l0aW9uUGl4ZWxzLngsIHNjcmVlblBvc2l0aW9uUGl4ZWxzLnksIDE2LCAxNiwgMCApO1xuXG5cblx0XHRcdFx0Ly8gcmVzdG9yZSBncmFwaGljc1xuXG5cdFx0XHRcdGdsLnVuaWZvcm0xaSggdW5pZm9ybXMucmVuZGVyVHlwZSwgMSApO1xuXHRcdFx0XHRzdGF0ZS5kaXNhYmxlKCBnbC5ERVBUSF9URVNUICk7XG5cblx0XHRcdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggZ2wuVEVYVFVSRTEgKTtcblx0XHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIGdsLlRFWFRVUkVfMkQsIHRlbXBUZXh0dXJlICk7XG5cdFx0XHRcdGdsLmRyYXdFbGVtZW50cyggZ2wuVFJJQU5HTEVTLCA2LCBnbC5VTlNJR05FRF9TSE9SVCwgMCApO1xuXG5cblx0XHRcdFx0Ly8gdXBkYXRlIG9iamVjdCBwb3NpdGlvbnNcblxuXHRcdFx0XHRmbGFyZS5wb3NpdGlvblNjcmVlbi5jb3B5KCBzY3JlZW5Qb3NpdGlvbiApO1xuXG5cdFx0XHRcdGlmICggZmxhcmUuY3VzdG9tVXBkYXRlQ2FsbGJhY2sgKSB7XG5cblx0XHRcdFx0XHRmbGFyZS5jdXN0b21VcGRhdGVDYWxsYmFjayggZmxhcmUgKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0ZmxhcmUudXBkYXRlTGVuc0ZsYXJlcygpO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyByZW5kZXIgZmxhcmVzXG5cblx0XHRcdFx0Z2wudW5pZm9ybTFpKCB1bmlmb3Jtcy5yZW5kZXJUeXBlLCAyICk7XG5cdFx0XHRcdHN0YXRlLmVuYWJsZSggZ2wuQkxFTkQgKTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaiA9IDAsIGpsID0gZmxhcmUubGVuc0ZsYXJlcy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHRcdHZhciBzcHJpdGUgPSBmbGFyZS5sZW5zRmxhcmVzWyBqIF07XG5cblx0XHRcdFx0XHRpZiAoIHNwcml0ZS5vcGFjaXR5ID4gMC4wMDEgJiYgc3ByaXRlLnNjYWxlID4gMC4wMDEgKSB7XG5cblx0XHRcdFx0XHRcdHNjcmVlblBvc2l0aW9uLnggPSBzcHJpdGUueDtcblx0XHRcdFx0XHRcdHNjcmVlblBvc2l0aW9uLnkgPSBzcHJpdGUueTtcblx0XHRcdFx0XHRcdHNjcmVlblBvc2l0aW9uLnogPSBzcHJpdGUuejtcblxuXHRcdFx0XHRcdFx0c2l6ZSA9IHNwcml0ZS5zaXplICogc3ByaXRlLnNjYWxlIC8gdmlld3BvcnQudztcblxuXHRcdFx0XHRcdFx0c2NhbGUueCA9IHNpemUgKiBpbnZBc3BlY3Q7XG5cdFx0XHRcdFx0XHRzY2FsZS55ID0gc2l6ZTtcblxuXHRcdFx0XHRcdFx0Z2wudW5pZm9ybTNmKCB1bmlmb3Jtcy5zY3JlZW5Qb3NpdGlvbiwgc2NyZWVuUG9zaXRpb24ueCwgc2NyZWVuUG9zaXRpb24ueSwgc2NyZWVuUG9zaXRpb24ueiApO1xuXHRcdFx0XHRcdFx0Z2wudW5pZm9ybTJmKCB1bmlmb3Jtcy5zY2FsZSwgc2NhbGUueCwgc2NhbGUueSApO1xuXHRcdFx0XHRcdFx0Z2wudW5pZm9ybTFmKCB1bmlmb3Jtcy5yb3RhdGlvbiwgc3ByaXRlLnJvdGF0aW9uICk7XG5cblx0XHRcdFx0XHRcdGdsLnVuaWZvcm0xZiggdW5pZm9ybXMub3BhY2l0eSwgc3ByaXRlLm9wYWNpdHkgKTtcblx0XHRcdFx0XHRcdGdsLnVuaWZvcm0zZiggdW5pZm9ybXMuY29sb3IsIHNwcml0ZS5jb2xvci5yLCBzcHJpdGUuY29sb3IuZywgc3ByaXRlLmNvbG9yLmIgKTtcblxuXHRcdFx0XHRcdFx0c3RhdGUuc2V0QmxlbmRpbmcoIHNwcml0ZS5ibGVuZGluZywgc3ByaXRlLmJsZW5kRXF1YXRpb24sIHNwcml0ZS5ibGVuZFNyYywgc3ByaXRlLmJsZW5kRHN0ICk7XG5cdFx0XHRcdFx0XHRyZW5kZXJlci5zZXRUZXh0dXJlMkQoIHNwcml0ZS50ZXh0dXJlLCAxICk7XG5cblx0XHRcdFx0XHRcdGdsLmRyYXdFbGVtZW50cyggZ2wuVFJJQU5HTEVTLCA2LCBnbC5VTlNJR05FRF9TSE9SVCwgMCApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gcmVzdG9yZSBnbFxuXG5cdFx0c3RhdGUuZW5hYmxlKCBnbC5DVUxMX0ZBQ0UgKTtcblx0XHRzdGF0ZS5lbmFibGUoIGdsLkRFUFRIX1RFU1QgKTtcblx0XHRzdGF0ZS5idWZmZXJzLmRlcHRoLnNldE1hc2soIHRydWUgKTtcblxuXHRcdHJlbmRlcmVyLnJlc2V0R0xTdGF0ZSgpO1xuXG5cdH07XG5cblx0ZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbSggc2hhZGVyICkge1xuXG5cdFx0dmFyIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG5cblx0XHR2YXIgZnJhZ21lbnRTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoIGdsLkZSQUdNRU5UX1NIQURFUiApO1xuXHRcdHZhciB2ZXJ0ZXhTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoIGdsLlZFUlRFWF9TSEFERVIgKTtcblxuXHRcdHZhciBwcmVmaXggPSBcInByZWNpc2lvbiBcIiArIHJlbmRlcmVyLmdldFByZWNpc2lvbigpICsgXCIgZmxvYXQ7XFxuXCI7XG5cblx0XHRnbC5zaGFkZXJTb3VyY2UoIGZyYWdtZW50U2hhZGVyLCBwcmVmaXggKyBzaGFkZXIuZnJhZ21lbnRTaGFkZXIgKTtcblx0XHRnbC5zaGFkZXJTb3VyY2UoIHZlcnRleFNoYWRlciwgcHJlZml4ICsgc2hhZGVyLnZlcnRleFNoYWRlciApO1xuXG5cdFx0Z2wuY29tcGlsZVNoYWRlciggZnJhZ21lbnRTaGFkZXIgKTtcblx0XHRnbC5jb21waWxlU2hhZGVyKCB2ZXJ0ZXhTaGFkZXIgKTtcblxuXHRcdGdsLmF0dGFjaFNoYWRlciggcHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIgKTtcblx0XHRnbC5hdHRhY2hTaGFkZXIoIHByb2dyYW0sIHZlcnRleFNoYWRlciApO1xuXG5cdFx0Z2wubGlua1Byb2dyYW0oIHByb2dyYW0gKTtcblxuXHRcdHJldHVybiBwcm9ncmFtO1xuXG5cdH1cblxufVxuXG4vKipcbiAqIEBhdXRob3IgbWlrYWVsIGVtdGluZ2VyIC8gaHR0cDovL2dvbW8uc2UvXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICovXG5cbmZ1bmN0aW9uIFNwcml0ZVBsdWdpbiggcmVuZGVyZXIsIHNwcml0ZXMgKSB7XG5cblx0dmFyIGdsID0gcmVuZGVyZXIuY29udGV4dDtcblx0dmFyIHN0YXRlID0gcmVuZGVyZXIuc3RhdGU7XG5cblx0dmFyIHZlcnRleEJ1ZmZlciwgZWxlbWVudEJ1ZmZlcjtcblx0dmFyIHByb2dyYW0sIGF0dHJpYnV0ZXMsIHVuaWZvcm1zO1xuXG5cdHZhciB0ZXh0dXJlO1xuXG5cdC8vIGRlY29tcG9zZSBtYXRyaXhXb3JsZFxuXG5cdHZhciBzcHJpdGVQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciBzcHJpdGVSb3RhdGlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdHZhciBzcHJpdGVTY2FsZSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0ZnVuY3Rpb24gaW5pdCgpIHtcblxuXHRcdHZhciB2ZXJ0aWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoIFtcblx0XHRcdC0gMC41LCAtIDAuNSwgIDAsIDAsXG5cdFx0XHQgIDAuNSwgLSAwLjUsICAxLCAwLFxuXHRcdFx0ICAwLjUsICAgMC41LCAgMSwgMSxcblx0XHRcdC0gMC41LCAgIDAuNSwgIDAsIDFcblx0XHRdICk7XG5cblx0XHR2YXIgZmFjZXMgPSBuZXcgVWludDE2QXJyYXkoIFtcblx0XHRcdDAsIDEsIDIsXG5cdFx0XHQwLCAyLCAzXG5cdFx0XSApO1xuXG5cdFx0dmVydGV4QnVmZmVyICA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuXHRcdGVsZW1lbnRCdWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcblxuXHRcdGdsLmJpbmRCdWZmZXIoIGdsLkFSUkFZX0JVRkZFUiwgdmVydGV4QnVmZmVyICk7XG5cdFx0Z2wuYnVmZmVyRGF0YSggZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0aWNlcywgZ2wuU1RBVElDX0RSQVcgKTtcblxuXHRcdGdsLmJpbmRCdWZmZXIoIGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBlbGVtZW50QnVmZmVyICk7XG5cdFx0Z2wuYnVmZmVyRGF0YSggZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGZhY2VzLCBnbC5TVEFUSUNfRFJBVyApO1xuXG5cdFx0cHJvZ3JhbSA9IGNyZWF0ZVByb2dyYW0oKTtcblxuXHRcdGF0dHJpYnV0ZXMgPSB7XG5cdFx0XHRwb3NpdGlvbjpcdFx0XHRnbC5nZXRBdHRyaWJMb2NhdGlvbiAoIHByb2dyYW0sICdwb3NpdGlvbicgKSxcblx0XHRcdHV2Olx0XHRcdFx0XHRnbC5nZXRBdHRyaWJMb2NhdGlvbiAoIHByb2dyYW0sICd1dicgKVxuXHRcdH07XG5cblx0XHR1bmlmb3JtcyA9IHtcblx0XHRcdHV2T2Zmc2V0Olx0XHRcdGdsLmdldFVuaWZvcm1Mb2NhdGlvbiggcHJvZ3JhbSwgJ3V2T2Zmc2V0JyApLFxuXHRcdFx0dXZTY2FsZTpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICd1dlNjYWxlJyApLFxuXG5cdFx0XHRyb3RhdGlvbjpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdyb3RhdGlvbicgKSxcblx0XHRcdHNjYWxlOlx0XHRcdFx0Z2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCAnc2NhbGUnICksXG5cblx0XHRcdGNvbG9yOlx0XHRcdFx0Z2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCAnY29sb3InICksXG5cdFx0XHRtYXA6XHRcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdtYXAnICksXG5cdFx0XHRvcGFjaXR5Olx0XHRcdGdsLmdldFVuaWZvcm1Mb2NhdGlvbiggcHJvZ3JhbSwgJ29wYWNpdHknICksXG5cblx0XHRcdG1vZGVsVmlld01hdHJpeDogXHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdtb2RlbFZpZXdNYXRyaXgnICksXG5cdFx0XHRwcm9qZWN0aW9uTWF0cml4Olx0Z2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCAncHJvamVjdGlvbk1hdHJpeCcgKSxcblxuXHRcdFx0Zm9nVHlwZTpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdmb2dUeXBlJyApLFxuXHRcdFx0Zm9nRGVuc2l0eTpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdmb2dEZW5zaXR5JyApLFxuXHRcdFx0Zm9nTmVhcjpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdmb2dOZWFyJyApLFxuXHRcdFx0Zm9nRmFyOlx0XHRcdFx0Z2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCAnZm9nRmFyJyApLFxuXHRcdFx0Zm9nQ29sb3I6XHRcdFx0Z2wuZ2V0VW5pZm9ybUxvY2F0aW9uKCBwcm9ncmFtLCAnZm9nQ29sb3InICksXG5cblx0XHRcdGFscGhhVGVzdDpcdFx0XHRnbC5nZXRVbmlmb3JtTG9jYXRpb24oIHByb2dyYW0sICdhbHBoYVRlc3QnIClcblx0XHR9O1xuXG5cdFx0dmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyggJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnLCAnY2FudmFzJyApO1xuXHRcdGNhbnZhcy53aWR0aCA9IDg7XG5cdFx0Y2FudmFzLmhlaWdodCA9IDg7XG5cblx0XHR2YXIgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCAnMmQnICk7XG5cdFx0Y29udGV4dC5maWxsU3R5bGUgPSAnd2hpdGUnO1xuXHRcdGNvbnRleHQuZmlsbFJlY3QoIDAsIDAsIDgsIDggKTtcblxuXHRcdHRleHR1cmUgPSBuZXcgVGV4dHVyZSggY2FudmFzICk7XG5cdFx0dGV4dHVyZS5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0fVxuXG5cdHRoaXMucmVuZGVyID0gZnVuY3Rpb24gKCBzY2VuZSwgY2FtZXJhICkge1xuXG5cdFx0aWYgKCBzcHJpdGVzLmxlbmd0aCA9PT0gMCApIHJldHVybjtcblxuXHRcdC8vIHNldHVwIGdsXG5cblx0XHRpZiAoIHByb2dyYW0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0aW5pdCgpO1xuXG5cdFx0fVxuXG5cdFx0Z2wudXNlUHJvZ3JhbSggcHJvZ3JhbSApO1xuXG5cdFx0c3RhdGUuaW5pdEF0dHJpYnV0ZXMoKTtcblx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIGF0dHJpYnV0ZXMucG9zaXRpb24gKTtcblx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIGF0dHJpYnV0ZXMudXYgKTtcblx0XHRzdGF0ZS5kaXNhYmxlVW51c2VkQXR0cmlidXRlcygpO1xuXG5cdFx0c3RhdGUuZGlzYWJsZSggZ2wuQ1VMTF9GQUNFICk7XG5cdFx0c3RhdGUuZW5hYmxlKCBnbC5CTEVORCApO1xuXG5cdFx0Z2wuYmluZEJ1ZmZlciggZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0ZXhCdWZmZXIgKTtcblx0XHRnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKCBhdHRyaWJ1dGVzLnBvc2l0aW9uLCAyLCBnbC5GTE9BVCwgZmFsc2UsIDIgKiA4LCAwICk7XG5cdFx0Z2wudmVydGV4QXR0cmliUG9pbnRlciggYXR0cmlidXRlcy51diwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAyICogOCwgOCApO1xuXG5cdFx0Z2wuYmluZEJ1ZmZlciggZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGVsZW1lbnRCdWZmZXIgKTtcblxuXHRcdGdsLnVuaWZvcm1NYXRyaXg0ZnYoIHVuaWZvcm1zLnByb2plY3Rpb25NYXRyaXgsIGZhbHNlLCBjYW1lcmEucHJvamVjdGlvbk1hdHJpeC5lbGVtZW50cyApO1xuXG5cdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggZ2wuVEVYVFVSRTAgKTtcblx0XHRnbC51bmlmb3JtMWkoIHVuaWZvcm1zLm1hcCwgMCApO1xuXG5cdFx0dmFyIG9sZEZvZ1R5cGUgPSAwO1xuXHRcdHZhciBzY2VuZUZvZ1R5cGUgPSAwO1xuXHRcdHZhciBmb2cgPSBzY2VuZS5mb2c7XG5cblx0XHRpZiAoIGZvZyApIHtcblxuXHRcdFx0Z2wudW5pZm9ybTNmKCB1bmlmb3Jtcy5mb2dDb2xvciwgZm9nLmNvbG9yLnIsIGZvZy5jb2xvci5nLCBmb2cuY29sb3IuYiApO1xuXG5cdFx0XHRpZiAoIGZvZy5pc0ZvZyApIHtcblxuXHRcdFx0XHRnbC51bmlmb3JtMWYoIHVuaWZvcm1zLmZvZ05lYXIsIGZvZy5uZWFyICk7XG5cdFx0XHRcdGdsLnVuaWZvcm0xZiggdW5pZm9ybXMuZm9nRmFyLCBmb2cuZmFyICk7XG5cblx0XHRcdFx0Z2wudW5pZm9ybTFpKCB1bmlmb3Jtcy5mb2dUeXBlLCAxICk7XG5cdFx0XHRcdG9sZEZvZ1R5cGUgPSAxO1xuXHRcdFx0XHRzY2VuZUZvZ1R5cGUgPSAxO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBmb2cuaXNGb2dFeHAyICkge1xuXG5cdFx0XHRcdGdsLnVuaWZvcm0xZiggdW5pZm9ybXMuZm9nRGVuc2l0eSwgZm9nLmRlbnNpdHkgKTtcblxuXHRcdFx0XHRnbC51bmlmb3JtMWkoIHVuaWZvcm1zLmZvZ1R5cGUsIDIgKTtcblx0XHRcdFx0b2xkRm9nVHlwZSA9IDI7XG5cdFx0XHRcdHNjZW5lRm9nVHlwZSA9IDI7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGdsLnVuaWZvcm0xaSggdW5pZm9ybXMuZm9nVHlwZSwgMCApO1xuXHRcdFx0b2xkRm9nVHlwZSA9IDA7XG5cdFx0XHRzY2VuZUZvZ1R5cGUgPSAwO1xuXG5cdFx0fVxuXG5cblx0XHQvLyB1cGRhdGUgcG9zaXRpb25zIGFuZCBzb3J0XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBzcHJpdGVzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBzcHJpdGUgPSBzcHJpdGVzWyBpIF07XG5cblx0XHRcdHNwcml0ZS5tb2RlbFZpZXdNYXRyaXgubXVsdGlwbHlNYXRyaWNlcyggY2FtZXJhLm1hdHJpeFdvcmxkSW52ZXJzZSwgc3ByaXRlLm1hdHJpeFdvcmxkICk7XG5cdFx0XHRzcHJpdGUueiA9IC0gc3ByaXRlLm1vZGVsVmlld01hdHJpeC5lbGVtZW50c1sgMTQgXTtcblxuXHRcdH1cblxuXHRcdHNwcml0ZXMuc29ydCggcGFpbnRlclNvcnRTdGFibGUgKTtcblxuXHRcdC8vIHJlbmRlciBhbGwgc3ByaXRlc1xuXG5cdFx0dmFyIHNjYWxlID0gW107XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBzcHJpdGVzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBzcHJpdGUgPSBzcHJpdGVzWyBpIF07XG5cdFx0XHR2YXIgbWF0ZXJpYWwgPSBzcHJpdGUubWF0ZXJpYWw7XG5cblx0XHRcdGlmICggbWF0ZXJpYWwudmlzaWJsZSA9PT0gZmFsc2UgKSBjb250aW51ZTtcblxuXHRcdFx0Z2wudW5pZm9ybTFmKCB1bmlmb3Jtcy5hbHBoYVRlc3QsIG1hdGVyaWFsLmFscGhhVGVzdCApO1xuXHRcdFx0Z2wudW5pZm9ybU1hdHJpeDRmdiggdW5pZm9ybXMubW9kZWxWaWV3TWF0cml4LCBmYWxzZSwgc3ByaXRlLm1vZGVsVmlld01hdHJpeC5lbGVtZW50cyApO1xuXG5cdFx0XHRzcHJpdGUubWF0cml4V29ybGQuZGVjb21wb3NlKCBzcHJpdGVQb3NpdGlvbiwgc3ByaXRlUm90YXRpb24sIHNwcml0ZVNjYWxlICk7XG5cblx0XHRcdHNjYWxlWyAwIF0gPSBzcHJpdGVTY2FsZS54O1xuXHRcdFx0c2NhbGVbIDEgXSA9IHNwcml0ZVNjYWxlLnk7XG5cblx0XHRcdHZhciBmb2dUeXBlID0gMDtcblxuXHRcdFx0aWYgKCBzY2VuZS5mb2cgJiYgbWF0ZXJpYWwuZm9nICkge1xuXG5cdFx0XHRcdGZvZ1R5cGUgPSBzY2VuZUZvZ1R5cGU7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvbGRGb2dUeXBlICE9PSBmb2dUeXBlICkge1xuXG5cdFx0XHRcdGdsLnVuaWZvcm0xaSggdW5pZm9ybXMuZm9nVHlwZSwgZm9nVHlwZSApO1xuXHRcdFx0XHRvbGRGb2dUeXBlID0gZm9nVHlwZTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG1hdGVyaWFsLm1hcCAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHRnbC51bmlmb3JtMmYoIHVuaWZvcm1zLnV2T2Zmc2V0LCBtYXRlcmlhbC5tYXAub2Zmc2V0LngsIG1hdGVyaWFsLm1hcC5vZmZzZXQueSApO1xuXHRcdFx0XHRnbC51bmlmb3JtMmYoIHVuaWZvcm1zLnV2U2NhbGUsIG1hdGVyaWFsLm1hcC5yZXBlYXQueCwgbWF0ZXJpYWwubWFwLnJlcGVhdC55ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Z2wudW5pZm9ybTJmKCB1bmlmb3Jtcy51dk9mZnNldCwgMCwgMCApO1xuXHRcdFx0XHRnbC51bmlmb3JtMmYoIHVuaWZvcm1zLnV2U2NhbGUsIDEsIDEgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRnbC51bmlmb3JtMWYoIHVuaWZvcm1zLm9wYWNpdHksIG1hdGVyaWFsLm9wYWNpdHkgKTtcblx0XHRcdGdsLnVuaWZvcm0zZiggdW5pZm9ybXMuY29sb3IsIG1hdGVyaWFsLmNvbG9yLnIsIG1hdGVyaWFsLmNvbG9yLmcsIG1hdGVyaWFsLmNvbG9yLmIgKTtcblxuXHRcdFx0Z2wudW5pZm9ybTFmKCB1bmlmb3Jtcy5yb3RhdGlvbiwgbWF0ZXJpYWwucm90YXRpb24gKTtcblx0XHRcdGdsLnVuaWZvcm0yZnYoIHVuaWZvcm1zLnNjYWxlLCBzY2FsZSApO1xuXG5cdFx0XHRzdGF0ZS5zZXRCbGVuZGluZyggbWF0ZXJpYWwuYmxlbmRpbmcsIG1hdGVyaWFsLmJsZW5kRXF1YXRpb24sIG1hdGVyaWFsLmJsZW5kU3JjLCBtYXRlcmlhbC5ibGVuZERzdCApO1xuXHRcdFx0c3RhdGUuYnVmZmVycy5kZXB0aC5zZXRUZXN0KCBtYXRlcmlhbC5kZXB0aFRlc3QgKTtcblx0XHRcdHN0YXRlLmJ1ZmZlcnMuZGVwdGguc2V0TWFzayggbWF0ZXJpYWwuZGVwdGhXcml0ZSApO1xuXG5cdFx0XHRpZiAoIG1hdGVyaWFsLm1hcCApIHtcblxuXHRcdFx0XHRyZW5kZXJlci5zZXRUZXh0dXJlMkQoIG1hdGVyaWFsLm1hcCwgMCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHJlbmRlcmVyLnNldFRleHR1cmUyRCggdGV4dHVyZSwgMCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGdsLmRyYXdFbGVtZW50cyggZ2wuVFJJQU5HTEVTLCA2LCBnbC5VTlNJR05FRF9TSE9SVCwgMCApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gcmVzdG9yZSBnbFxuXG5cdFx0c3RhdGUuZW5hYmxlKCBnbC5DVUxMX0ZBQ0UgKTtcblxuXHRcdHJlbmRlcmVyLnJlc2V0R0xTdGF0ZSgpO1xuXG5cdH07XG5cblx0ZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbSgpIHtcblxuXHRcdHZhciBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuXG5cdFx0dmFyIHZlcnRleFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlciggZ2wuVkVSVEVYX1NIQURFUiApO1xuXHRcdHZhciBmcmFnbWVudFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlciggZ2wuRlJBR01FTlRfU0hBREVSICk7XG5cblx0XHRnbC5zaGFkZXJTb3VyY2UoIHZlcnRleFNoYWRlciwgW1xuXG5cdFx0XHQncHJlY2lzaW9uICcgKyByZW5kZXJlci5nZXRQcmVjaXNpb24oKSArICcgZmxvYXQ7JyxcblxuXHRcdFx0J3VuaWZvcm0gbWF0NCBtb2RlbFZpZXdNYXRyaXg7Jyxcblx0XHRcdCd1bmlmb3JtIG1hdDQgcHJvamVjdGlvbk1hdHJpeDsnLFxuXHRcdFx0J3VuaWZvcm0gZmxvYXQgcm90YXRpb247Jyxcblx0XHRcdCd1bmlmb3JtIHZlYzIgc2NhbGU7Jyxcblx0XHRcdCd1bmlmb3JtIHZlYzIgdXZPZmZzZXQ7Jyxcblx0XHRcdCd1bmlmb3JtIHZlYzIgdXZTY2FsZTsnLFxuXG5cdFx0XHQnYXR0cmlidXRlIHZlYzIgcG9zaXRpb247Jyxcblx0XHRcdCdhdHRyaWJ1dGUgdmVjMiB1djsnLFxuXG5cdFx0XHQndmFyeWluZyB2ZWMyIHZVVjsnLFxuXG5cdFx0XHQndm9pZCBtYWluKCkgeycsXG5cblx0XHRcdFx0J3ZVViA9IHV2T2Zmc2V0ICsgdXYgKiB1dlNjYWxlOycsXG5cblx0XHRcdFx0J3ZlYzIgYWxpZ25lZFBvc2l0aW9uID0gcG9zaXRpb24gKiBzY2FsZTsnLFxuXG5cdFx0XHRcdCd2ZWMyIHJvdGF0ZWRQb3NpdGlvbjsnLFxuXHRcdFx0XHQncm90YXRlZFBvc2l0aW9uLnggPSBjb3MoIHJvdGF0aW9uICkgKiBhbGlnbmVkUG9zaXRpb24ueCAtIHNpbiggcm90YXRpb24gKSAqIGFsaWduZWRQb3NpdGlvbi55OycsXG5cdFx0XHRcdCdyb3RhdGVkUG9zaXRpb24ueSA9IHNpbiggcm90YXRpb24gKSAqIGFsaWduZWRQb3NpdGlvbi54ICsgY29zKCByb3RhdGlvbiApICogYWxpZ25lZFBvc2l0aW9uLnk7JyxcblxuXHRcdFx0XHQndmVjNCBmaW5hbFBvc2l0aW9uOycsXG5cblx0XHRcdFx0J2ZpbmFsUG9zaXRpb24gPSBtb2RlbFZpZXdNYXRyaXggKiB2ZWM0KCAwLjAsIDAuMCwgMC4wLCAxLjAgKTsnLFxuXHRcdFx0XHQnZmluYWxQb3NpdGlvbi54eSArPSByb3RhdGVkUG9zaXRpb247Jyxcblx0XHRcdFx0J2ZpbmFsUG9zaXRpb24gPSBwcm9qZWN0aW9uTWF0cml4ICogZmluYWxQb3NpdGlvbjsnLFxuXG5cdFx0XHRcdCdnbF9Qb3NpdGlvbiA9IGZpbmFsUG9zaXRpb247JyxcblxuXHRcdFx0J30nXG5cblx0XHRdLmpvaW4oICdcXG4nICkgKTtcblxuXHRcdGdsLnNoYWRlclNvdXJjZSggZnJhZ21lbnRTaGFkZXIsIFtcblxuXHRcdFx0J3ByZWNpc2lvbiAnICsgcmVuZGVyZXIuZ2V0UHJlY2lzaW9uKCkgKyAnIGZsb2F0OycsXG5cblx0XHRcdCd1bmlmb3JtIHZlYzMgY29sb3I7Jyxcblx0XHRcdCd1bmlmb3JtIHNhbXBsZXIyRCBtYXA7Jyxcblx0XHRcdCd1bmlmb3JtIGZsb2F0IG9wYWNpdHk7JyxcblxuXHRcdFx0J3VuaWZvcm0gaW50IGZvZ1R5cGU7Jyxcblx0XHRcdCd1bmlmb3JtIHZlYzMgZm9nQ29sb3I7Jyxcblx0XHRcdCd1bmlmb3JtIGZsb2F0IGZvZ0RlbnNpdHk7Jyxcblx0XHRcdCd1bmlmb3JtIGZsb2F0IGZvZ05lYXI7Jyxcblx0XHRcdCd1bmlmb3JtIGZsb2F0IGZvZ0ZhcjsnLFxuXHRcdFx0J3VuaWZvcm0gZmxvYXQgYWxwaGFUZXN0OycsXG5cblx0XHRcdCd2YXJ5aW5nIHZlYzIgdlVWOycsXG5cblx0XHRcdCd2b2lkIG1haW4oKSB7JyxcblxuXHRcdFx0XHQndmVjNCB0ZXh0dXJlID0gdGV4dHVyZTJEKCBtYXAsIHZVViApOycsXG5cblx0XHRcdFx0J2lmICggdGV4dHVyZS5hIDwgYWxwaGFUZXN0ICkgZGlzY2FyZDsnLFxuXG5cdFx0XHRcdCdnbF9GcmFnQ29sb3IgPSB2ZWM0KCBjb2xvciAqIHRleHR1cmUueHl6LCB0ZXh0dXJlLmEgKiBvcGFjaXR5ICk7JyxcblxuXHRcdFx0XHQnaWYgKCBmb2dUeXBlID4gMCApIHsnLFxuXG5cdFx0XHRcdFx0J2Zsb2F0IGRlcHRoID0gZ2xfRnJhZ0Nvb3JkLnogLyBnbF9GcmFnQ29vcmQudzsnLFxuXHRcdFx0XHRcdCdmbG9hdCBmb2dGYWN0b3IgPSAwLjA7JyxcblxuXHRcdFx0XHRcdCdpZiAoIGZvZ1R5cGUgPT0gMSApIHsnLFxuXG5cdFx0XHRcdFx0XHQnZm9nRmFjdG9yID0gc21vb3Roc3RlcCggZm9nTmVhciwgZm9nRmFyLCBkZXB0aCApOycsXG5cblx0XHRcdFx0XHQnfSBlbHNlIHsnLFxuXG5cdFx0XHRcdFx0XHQnY29uc3QgZmxvYXQgTE9HMiA9IDEuNDQyNjk1OycsXG5cdFx0XHRcdFx0XHQnZm9nRmFjdG9yID0gZXhwMiggLSBmb2dEZW5zaXR5ICogZm9nRGVuc2l0eSAqIGRlcHRoICogZGVwdGggKiBMT0cyICk7Jyxcblx0XHRcdFx0XHRcdCdmb2dGYWN0b3IgPSAxLjAgLSBjbGFtcCggZm9nRmFjdG9yLCAwLjAsIDEuMCApOycsXG5cblx0XHRcdFx0XHQnfScsXG5cblx0XHRcdFx0XHQnZ2xfRnJhZ0NvbG9yID0gbWl4KCBnbF9GcmFnQ29sb3IsIHZlYzQoIGZvZ0NvbG9yLCBnbF9GcmFnQ29sb3IudyApLCBmb2dGYWN0b3IgKTsnLFxuXG5cdFx0XHRcdCd9JyxcblxuXHRcdFx0J30nXG5cblx0XHRdLmpvaW4oICdcXG4nICkgKTtcblxuXHRcdGdsLmNvbXBpbGVTaGFkZXIoIHZlcnRleFNoYWRlciApO1xuXHRcdGdsLmNvbXBpbGVTaGFkZXIoIGZyYWdtZW50U2hhZGVyICk7XG5cblx0XHRnbC5hdHRhY2hTaGFkZXIoIHByb2dyYW0sIHZlcnRleFNoYWRlciApO1xuXHRcdGdsLmF0dGFjaFNoYWRlciggcHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIgKTtcblxuXHRcdGdsLmxpbmtQcm9ncmFtKCBwcm9ncmFtICk7XG5cblx0XHRyZXR1cm4gcHJvZ3JhbTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcGFpbnRlclNvcnRTdGFibGUoIGEsIGIgKSB7XG5cblx0XHRpZiAoIGEucmVuZGVyT3JkZXIgIT09IGIucmVuZGVyT3JkZXIgKSB7XG5cblx0XHRcdHJldHVybiBhLnJlbmRlck9yZGVyIC0gYi5yZW5kZXJPcmRlcjtcblxuXHRcdH0gZWxzZSBpZiAoIGEueiAhPT0gYi56ICkge1xuXG5cdFx0XHRyZXR1cm4gYi56IC0gYS56O1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0cmV0dXJuIGIuaWQgLSBhLmlkO1xuXG5cdFx0fVxuXG5cdH1cblxufVxuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICovXG5cbnZhciBtYXRlcmlhbElkID0gMDtcblxuZnVuY3Rpb24gTWF0ZXJpYWwoKSB7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCAnaWQnLCB7IHZhbHVlOiBtYXRlcmlhbElkICsrIH0gKTtcblxuXHR0aGlzLnV1aWQgPSBfTWF0aC5nZW5lcmF0ZVVVSUQoKTtcblxuXHR0aGlzLm5hbWUgPSAnJztcblx0dGhpcy50eXBlID0gJ01hdGVyaWFsJztcblxuXHR0aGlzLmZvZyA9IHRydWU7XG5cdHRoaXMubGlnaHRzID0gdHJ1ZTtcblxuXHR0aGlzLmJsZW5kaW5nID0gTm9ybWFsQmxlbmRpbmc7XG5cdHRoaXMuc2lkZSA9IEZyb250U2lkZTtcblx0dGhpcy5zaGFkaW5nID0gU21vb3RoU2hhZGluZzsgLy8gVEhSRUUuRmxhdFNoYWRpbmcsIFRIUkVFLlNtb290aFNoYWRpbmdcblx0dGhpcy52ZXJ0ZXhDb2xvcnMgPSBOb0NvbG9yczsgLy8gVEhSRUUuTm9Db2xvcnMsIFRIUkVFLlZlcnRleENvbG9ycywgVEhSRUUuRmFjZUNvbG9yc1xuXG5cdHRoaXMub3BhY2l0eSA9IDE7XG5cdHRoaXMudHJhbnNwYXJlbnQgPSBmYWxzZTtcblxuXHR0aGlzLmJsZW5kU3JjID0gU3JjQWxwaGFGYWN0b3I7XG5cdHRoaXMuYmxlbmREc3QgPSBPbmVNaW51c1NyY0FscGhhRmFjdG9yO1xuXHR0aGlzLmJsZW5kRXF1YXRpb24gPSBBZGRFcXVhdGlvbjtcblx0dGhpcy5ibGVuZFNyY0FscGhhID0gbnVsbDtcblx0dGhpcy5ibGVuZERzdEFscGhhID0gbnVsbDtcblx0dGhpcy5ibGVuZEVxdWF0aW9uQWxwaGEgPSBudWxsO1xuXG5cdHRoaXMuZGVwdGhGdW5jID0gTGVzc0VxdWFsRGVwdGg7XG5cdHRoaXMuZGVwdGhUZXN0ID0gdHJ1ZTtcblx0dGhpcy5kZXB0aFdyaXRlID0gdHJ1ZTtcblxuXHR0aGlzLmNsaXBwaW5nUGxhbmVzID0gbnVsbDtcblx0dGhpcy5jbGlwSW50ZXJzZWN0aW9uID0gZmFsc2U7XG5cdHRoaXMuY2xpcFNoYWRvd3MgPSBmYWxzZTtcblxuXHR0aGlzLmNvbG9yV3JpdGUgPSB0cnVlO1xuXG5cdHRoaXMucHJlY2lzaW9uID0gbnVsbDsgLy8gb3ZlcnJpZGUgdGhlIHJlbmRlcmVyJ3MgZGVmYXVsdCBwcmVjaXNpb24gZm9yIHRoaXMgbWF0ZXJpYWxcblxuXHR0aGlzLnBvbHlnb25PZmZzZXQgPSBmYWxzZTtcblx0dGhpcy5wb2x5Z29uT2Zmc2V0RmFjdG9yID0gMDtcblx0dGhpcy5wb2x5Z29uT2Zmc2V0VW5pdHMgPSAwO1xuXG5cdHRoaXMuZGl0aGVyaW5nID0gZmFsc2U7XG5cblx0dGhpcy5hbHBoYVRlc3QgPSAwO1xuXHR0aGlzLnByZW11bHRpcGxpZWRBbHBoYSA9IGZhbHNlO1xuXG5cdHRoaXMub3ZlcmRyYXcgPSAwOyAvLyBPdmVyZHJhd24gcGl4ZWxzICh0eXBpY2FsbHkgYmV0d2VlbiAwIGFuZCAxKSBmb3IgZml4aW5nIGFudGlhbGlhc2luZyBnYXBzIGluIENhbnZhc1JlbmRlcmVyXG5cblx0dGhpcy52aXNpYmxlID0gdHJ1ZTtcblxuXHR0aGlzLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBNYXRlcmlhbC5wcm90b3R5cGUsIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUsIHtcblxuXHRpc01hdGVyaWFsOiB0cnVlLFxuXG5cdHNldFZhbHVlczogZnVuY3Rpb24gKCB2YWx1ZXMgKSB7XG5cblx0XHRpZiAoIHZhbHVlcyA9PT0gdW5kZWZpbmVkICkgcmV0dXJuO1xuXG5cdFx0Zm9yICggdmFyIGtleSBpbiB2YWx1ZXMgKSB7XG5cblx0XHRcdHZhciBuZXdWYWx1ZSA9IHZhbHVlc1sga2V5IF07XG5cblx0XHRcdGlmICggbmV3VmFsdWUgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oIFwiVEhSRUUuTWF0ZXJpYWw6ICdcIiArIGtleSArIFwiJyBwYXJhbWV0ZXIgaXMgdW5kZWZpbmVkLlwiICk7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBjdXJyZW50VmFsdWUgPSB0aGlzWyBrZXkgXTtcblxuXHRcdFx0aWYgKCBjdXJyZW50VmFsdWUgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oIFwiVEhSRUUuXCIgKyB0aGlzLnR5cGUgKyBcIjogJ1wiICsga2V5ICsgXCInIGlzIG5vdCBhIHByb3BlcnR5IG9mIHRoaXMgbWF0ZXJpYWwuXCIgKTtcblx0XHRcdFx0Y29udGludWU7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBjdXJyZW50VmFsdWUgJiYgY3VycmVudFZhbHVlLmlzQ29sb3IgKSB7XG5cblx0XHRcdFx0Y3VycmVudFZhbHVlLnNldCggbmV3VmFsdWUgKTtcblxuXHRcdFx0fSBlbHNlIGlmICggKCBjdXJyZW50VmFsdWUgJiYgY3VycmVudFZhbHVlLmlzVmVjdG9yMyApICYmICggbmV3VmFsdWUgJiYgbmV3VmFsdWUuaXNWZWN0b3IzICkgKSB7XG5cblx0XHRcdFx0Y3VycmVudFZhbHVlLmNvcHkoIG5ld1ZhbHVlICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGtleSA9PT0gJ292ZXJkcmF3JyApIHtcblxuXHRcdFx0XHQvLyBlbnN1cmUgb3ZlcmRyYXcgaXMgYmFja3dhcmRzLWNvbXBhdGlibGUgd2l0aCBsZWdhY3kgYm9vbGVhbiB0eXBlXG5cdFx0XHRcdHRoaXNbIGtleSBdID0gTnVtYmVyKCBuZXdWYWx1ZSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHRoaXNbIGtleSBdID0gbmV3VmFsdWU7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCBtZXRhICkge1xuXG5cdFx0dmFyIGlzUm9vdCA9IG1ldGEgPT09IHVuZGVmaW5lZDtcblxuXHRcdGlmICggaXNSb290ICkge1xuXG5cdFx0XHRtZXRhID0ge1xuXHRcdFx0XHR0ZXh0dXJlczoge30sXG5cdFx0XHRcdGltYWdlczoge31cblx0XHRcdH07XG5cblx0XHR9XG5cblx0XHR2YXIgZGF0YSA9IHtcblx0XHRcdG1ldGFkYXRhOiB7XG5cdFx0XHRcdHZlcnNpb246IDQuNSxcblx0XHRcdFx0dHlwZTogJ01hdGVyaWFsJyxcblx0XHRcdFx0Z2VuZXJhdG9yOiAnTWF0ZXJpYWwudG9KU09OJ1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHQvLyBzdGFuZGFyZCBNYXRlcmlhbCBzZXJpYWxpemF0aW9uXG5cdFx0ZGF0YS51dWlkID0gdGhpcy51dWlkO1xuXHRcdGRhdGEudHlwZSA9IHRoaXMudHlwZTtcblxuXHRcdGlmICggdGhpcy5uYW1lICE9PSAnJyApIGRhdGEubmFtZSA9IHRoaXMubmFtZTtcblxuXHRcdGlmICggdGhpcy5jb2xvciAmJiB0aGlzLmNvbG9yLmlzQ29sb3IgKSBkYXRhLmNvbG9yID0gdGhpcy5jb2xvci5nZXRIZXgoKTtcblxuXHRcdGlmICggdGhpcy5yb3VnaG5lc3MgIT09IHVuZGVmaW5lZCApIGRhdGEucm91Z2huZXNzID0gdGhpcy5yb3VnaG5lc3M7XG5cdFx0aWYgKCB0aGlzLm1ldGFsbmVzcyAhPT0gdW5kZWZpbmVkICkgZGF0YS5tZXRhbG5lc3MgPSB0aGlzLm1ldGFsbmVzcztcblxuXHRcdGlmICggdGhpcy5lbWlzc2l2ZSAmJiB0aGlzLmVtaXNzaXZlLmlzQ29sb3IgKSBkYXRhLmVtaXNzaXZlID0gdGhpcy5lbWlzc2l2ZS5nZXRIZXgoKTtcblx0XHRpZiAoIHRoaXMuc3BlY3VsYXIgJiYgdGhpcy5zcGVjdWxhci5pc0NvbG9yICkgZGF0YS5zcGVjdWxhciA9IHRoaXMuc3BlY3VsYXIuZ2V0SGV4KCk7XG5cdFx0aWYgKCB0aGlzLnNoaW5pbmVzcyAhPT0gdW5kZWZpbmVkICkgZGF0YS5zaGluaW5lc3MgPSB0aGlzLnNoaW5pbmVzcztcblx0XHRpZiAoIHRoaXMuY2xlYXJDb2F0ICE9PSB1bmRlZmluZWQgKSBkYXRhLmNsZWFyQ29hdCA9IHRoaXMuY2xlYXJDb2F0O1xuXHRcdGlmICggdGhpcy5jbGVhckNvYXRSb3VnaG5lc3MgIT09IHVuZGVmaW5lZCApIGRhdGEuY2xlYXJDb2F0Um91Z2huZXNzID0gdGhpcy5jbGVhckNvYXRSb3VnaG5lc3M7XG5cblx0XHRpZiAoIHRoaXMubWFwICYmIHRoaXMubWFwLmlzVGV4dHVyZSApIGRhdGEubWFwID0gdGhpcy5tYXAudG9KU09OKCBtZXRhICkudXVpZDtcblx0XHRpZiAoIHRoaXMuYWxwaGFNYXAgJiYgdGhpcy5hbHBoYU1hcC5pc1RleHR1cmUgKSBkYXRhLmFscGhhTWFwID0gdGhpcy5hbHBoYU1hcC50b0pTT04oIG1ldGEgKS51dWlkO1xuXHRcdGlmICggdGhpcy5saWdodE1hcCAmJiB0aGlzLmxpZ2h0TWFwLmlzVGV4dHVyZSApIGRhdGEubGlnaHRNYXAgPSB0aGlzLmxpZ2h0TWFwLnRvSlNPTiggbWV0YSApLnV1aWQ7XG5cdFx0aWYgKCB0aGlzLmJ1bXBNYXAgJiYgdGhpcy5idW1wTWFwLmlzVGV4dHVyZSApIHtcblxuXHRcdFx0ZGF0YS5idW1wTWFwID0gdGhpcy5idW1wTWFwLnRvSlNPTiggbWV0YSApLnV1aWQ7XG5cdFx0XHRkYXRhLmJ1bXBTY2FsZSA9IHRoaXMuYnVtcFNjYWxlO1xuXG5cdFx0fVxuXHRcdGlmICggdGhpcy5ub3JtYWxNYXAgJiYgdGhpcy5ub3JtYWxNYXAuaXNUZXh0dXJlICkge1xuXG5cdFx0XHRkYXRhLm5vcm1hbE1hcCA9IHRoaXMubm9ybWFsTWFwLnRvSlNPTiggbWV0YSApLnV1aWQ7XG5cdFx0XHRkYXRhLm5vcm1hbFNjYWxlID0gdGhpcy5ub3JtYWxTY2FsZS50b0FycmF5KCk7XG5cblx0XHR9XG5cdFx0aWYgKCB0aGlzLmRpc3BsYWNlbWVudE1hcCAmJiB0aGlzLmRpc3BsYWNlbWVudE1hcC5pc1RleHR1cmUgKSB7XG5cblx0XHRcdGRhdGEuZGlzcGxhY2VtZW50TWFwID0gdGhpcy5kaXNwbGFjZW1lbnRNYXAudG9KU09OKCBtZXRhICkudXVpZDtcblx0XHRcdGRhdGEuZGlzcGxhY2VtZW50U2NhbGUgPSB0aGlzLmRpc3BsYWNlbWVudFNjYWxlO1xuXHRcdFx0ZGF0YS5kaXNwbGFjZW1lbnRCaWFzID0gdGhpcy5kaXNwbGFjZW1lbnRCaWFzO1xuXG5cdFx0fVxuXHRcdGlmICggdGhpcy5yb3VnaG5lc3NNYXAgJiYgdGhpcy5yb3VnaG5lc3NNYXAuaXNUZXh0dXJlICkgZGF0YS5yb3VnaG5lc3NNYXAgPSB0aGlzLnJvdWdobmVzc01hcC50b0pTT04oIG1ldGEgKS51dWlkO1xuXHRcdGlmICggdGhpcy5tZXRhbG5lc3NNYXAgJiYgdGhpcy5tZXRhbG5lc3NNYXAuaXNUZXh0dXJlICkgZGF0YS5tZXRhbG5lc3NNYXAgPSB0aGlzLm1ldGFsbmVzc01hcC50b0pTT04oIG1ldGEgKS51dWlkO1xuXG5cdFx0aWYgKCB0aGlzLmVtaXNzaXZlTWFwICYmIHRoaXMuZW1pc3NpdmVNYXAuaXNUZXh0dXJlICkgZGF0YS5lbWlzc2l2ZU1hcCA9IHRoaXMuZW1pc3NpdmVNYXAudG9KU09OKCBtZXRhICkudXVpZDtcblx0XHRpZiAoIHRoaXMuc3BlY3VsYXJNYXAgJiYgdGhpcy5zcGVjdWxhck1hcC5pc1RleHR1cmUgKSBkYXRhLnNwZWN1bGFyTWFwID0gdGhpcy5zcGVjdWxhck1hcC50b0pTT04oIG1ldGEgKS51dWlkO1xuXG5cdFx0aWYgKCB0aGlzLmVudk1hcCAmJiB0aGlzLmVudk1hcC5pc1RleHR1cmUgKSB7XG5cblx0XHRcdGRhdGEuZW52TWFwID0gdGhpcy5lbnZNYXAudG9KU09OKCBtZXRhICkudXVpZDtcblx0XHRcdGRhdGEucmVmbGVjdGl2aXR5ID0gdGhpcy5yZWZsZWN0aXZpdHk7IC8vIFNjYWxlIGJlaGluZCBlbnZNYXBcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ncmFkaWVudE1hcCAmJiB0aGlzLmdyYWRpZW50TWFwLmlzVGV4dHVyZSApIHtcblxuXHRcdFx0ZGF0YS5ncmFkaWVudE1hcCA9IHRoaXMuZ3JhZGllbnRNYXAudG9KU09OKCBtZXRhICkudXVpZDtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5zaXplICE9PSB1bmRlZmluZWQgKSBkYXRhLnNpemUgPSB0aGlzLnNpemU7XG5cdFx0aWYgKCB0aGlzLnNpemVBdHRlbnVhdGlvbiAhPT0gdW5kZWZpbmVkICkgZGF0YS5zaXplQXR0ZW51YXRpb24gPSB0aGlzLnNpemVBdHRlbnVhdGlvbjtcblxuXHRcdGlmICggdGhpcy5ibGVuZGluZyAhPT0gTm9ybWFsQmxlbmRpbmcgKSBkYXRhLmJsZW5kaW5nID0gdGhpcy5ibGVuZGluZztcblx0XHRpZiAoIHRoaXMuc2hhZGluZyAhPT0gU21vb3RoU2hhZGluZyApIGRhdGEuc2hhZGluZyA9IHRoaXMuc2hhZGluZztcblx0XHRpZiAoIHRoaXMuc2lkZSAhPT0gRnJvbnRTaWRlICkgZGF0YS5zaWRlID0gdGhpcy5zaWRlO1xuXHRcdGlmICggdGhpcy52ZXJ0ZXhDb2xvcnMgIT09IE5vQ29sb3JzICkgZGF0YS52ZXJ0ZXhDb2xvcnMgPSB0aGlzLnZlcnRleENvbG9ycztcblxuXHRcdGlmICggdGhpcy5vcGFjaXR5IDwgMSApIGRhdGEub3BhY2l0eSA9IHRoaXMub3BhY2l0eTtcblx0XHRpZiAoIHRoaXMudHJhbnNwYXJlbnQgPT09IHRydWUgKSBkYXRhLnRyYW5zcGFyZW50ID0gdGhpcy50cmFuc3BhcmVudDtcblxuXHRcdGRhdGEuZGVwdGhGdW5jID0gdGhpcy5kZXB0aEZ1bmM7XG5cdFx0ZGF0YS5kZXB0aFRlc3QgPSB0aGlzLmRlcHRoVGVzdDtcblx0XHRkYXRhLmRlcHRoV3JpdGUgPSB0aGlzLmRlcHRoV3JpdGU7XG5cblx0XHRpZiAoIHRoaXMuYWxwaGFUZXN0ID4gMCApIGRhdGEuYWxwaGFUZXN0ID0gdGhpcy5hbHBoYVRlc3Q7XG5cdFx0aWYgKCB0aGlzLnByZW11bHRpcGxpZWRBbHBoYSA9PT0gdHJ1ZSApIGRhdGEucHJlbXVsdGlwbGllZEFscGhhID0gdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE7XG5cdFx0aWYgKCB0aGlzLndpcmVmcmFtZSA9PT0gdHJ1ZSApIGRhdGEud2lyZWZyYW1lID0gdGhpcy53aXJlZnJhbWU7XG5cdFx0aWYgKCB0aGlzLndpcmVmcmFtZUxpbmV3aWR0aCA+IDEgKSBkYXRhLndpcmVmcmFtZUxpbmV3aWR0aCA9IHRoaXMud2lyZWZyYW1lTGluZXdpZHRoO1xuXHRcdGlmICggdGhpcy53aXJlZnJhbWVMaW5lY2FwICE9PSAncm91bmQnICkgZGF0YS53aXJlZnJhbWVMaW5lY2FwID0gdGhpcy53aXJlZnJhbWVMaW5lY2FwO1xuXHRcdGlmICggdGhpcy53aXJlZnJhbWVMaW5lam9pbiAhPT0gJ3JvdW5kJyApIGRhdGEud2lyZWZyYW1lTGluZWpvaW4gPSB0aGlzLndpcmVmcmFtZUxpbmVqb2luO1xuXG5cdFx0ZGF0YS5za2lubmluZyA9IHRoaXMuc2tpbm5pbmc7XG5cdFx0ZGF0YS5tb3JwaFRhcmdldHMgPSB0aGlzLm1vcnBoVGFyZ2V0cztcblxuXHRcdGRhdGEuZGl0aGVyaW5nID0gdGhpcy5kaXRoZXJpbmc7XG5cblx0XHQvLyBUT0RPOiBDb3BpZWQgZnJvbSBPYmplY3QzRC50b0pTT05cblxuXHRcdGZ1bmN0aW9uIGV4dHJhY3RGcm9tQ2FjaGUoIGNhY2hlICkge1xuXG5cdFx0XHR2YXIgdmFsdWVzID0gW107XG5cblx0XHRcdGZvciAoIHZhciBrZXkgaW4gY2FjaGUgKSB7XG5cblx0XHRcdFx0dmFyIGRhdGEgPSBjYWNoZVsga2V5IF07XG5cdFx0XHRcdGRlbGV0ZSBkYXRhLm1ldGFkYXRhO1xuXHRcdFx0XHR2YWx1ZXMucHVzaCggZGF0YSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB2YWx1ZXM7XG5cblx0XHR9XG5cblx0XHRpZiAoIGlzUm9vdCApIHtcblxuXHRcdFx0dmFyIHRleHR1cmVzID0gZXh0cmFjdEZyb21DYWNoZSggbWV0YS50ZXh0dXJlcyApO1xuXHRcdFx0dmFyIGltYWdlcyA9IGV4dHJhY3RGcm9tQ2FjaGUoIG1ldGEuaW1hZ2VzICk7XG5cblx0XHRcdGlmICggdGV4dHVyZXMubGVuZ3RoID4gMCApIGRhdGEudGV4dHVyZXMgPSB0ZXh0dXJlcztcblx0XHRcdGlmICggaW1hZ2VzLmxlbmd0aCA+IDAgKSBkYXRhLmltYWdlcyA9IGltYWdlcztcblxuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0dGhpcy5uYW1lID0gc291cmNlLm5hbWU7XG5cblx0XHR0aGlzLmZvZyA9IHNvdXJjZS5mb2c7XG5cdFx0dGhpcy5saWdodHMgPSBzb3VyY2UubGlnaHRzO1xuXG5cdFx0dGhpcy5ibGVuZGluZyA9IHNvdXJjZS5ibGVuZGluZztcblx0XHR0aGlzLnNpZGUgPSBzb3VyY2Uuc2lkZTtcblx0XHR0aGlzLnNoYWRpbmcgPSBzb3VyY2Uuc2hhZGluZztcblx0XHR0aGlzLnZlcnRleENvbG9ycyA9IHNvdXJjZS52ZXJ0ZXhDb2xvcnM7XG5cblx0XHR0aGlzLm9wYWNpdHkgPSBzb3VyY2Uub3BhY2l0eTtcblx0XHR0aGlzLnRyYW5zcGFyZW50ID0gc291cmNlLnRyYW5zcGFyZW50O1xuXG5cdFx0dGhpcy5ibGVuZFNyYyA9IHNvdXJjZS5ibGVuZFNyYztcblx0XHR0aGlzLmJsZW5kRHN0ID0gc291cmNlLmJsZW5kRHN0O1xuXHRcdHRoaXMuYmxlbmRFcXVhdGlvbiA9IHNvdXJjZS5ibGVuZEVxdWF0aW9uO1xuXHRcdHRoaXMuYmxlbmRTcmNBbHBoYSA9IHNvdXJjZS5ibGVuZFNyY0FscGhhO1xuXHRcdHRoaXMuYmxlbmREc3RBbHBoYSA9IHNvdXJjZS5ibGVuZERzdEFscGhhO1xuXHRcdHRoaXMuYmxlbmRFcXVhdGlvbkFscGhhID0gc291cmNlLmJsZW5kRXF1YXRpb25BbHBoYTtcblxuXHRcdHRoaXMuZGVwdGhGdW5jID0gc291cmNlLmRlcHRoRnVuYztcblx0XHR0aGlzLmRlcHRoVGVzdCA9IHNvdXJjZS5kZXB0aFRlc3Q7XG5cdFx0dGhpcy5kZXB0aFdyaXRlID0gc291cmNlLmRlcHRoV3JpdGU7XG5cblx0XHR0aGlzLmNvbG9yV3JpdGUgPSBzb3VyY2UuY29sb3JXcml0ZTtcblxuXHRcdHRoaXMucHJlY2lzaW9uID0gc291cmNlLnByZWNpc2lvbjtcblxuXHRcdHRoaXMucG9seWdvbk9mZnNldCA9IHNvdXJjZS5wb2x5Z29uT2Zmc2V0O1xuXHRcdHRoaXMucG9seWdvbk9mZnNldEZhY3RvciA9IHNvdXJjZS5wb2x5Z29uT2Zmc2V0RmFjdG9yO1xuXHRcdHRoaXMucG9seWdvbk9mZnNldFVuaXRzID0gc291cmNlLnBvbHlnb25PZmZzZXRVbml0cztcblxuXHRcdHRoaXMuZGl0aGVyaW5nID0gc291cmNlLmRpdGhlcmluZztcblxuXHRcdHRoaXMuYWxwaGFUZXN0ID0gc291cmNlLmFscGhhVGVzdDtcblxuXHRcdHRoaXMucHJlbXVsdGlwbGllZEFscGhhID0gc291cmNlLnByZW11bHRpcGxpZWRBbHBoYTtcblxuXHRcdHRoaXMub3ZlcmRyYXcgPSBzb3VyY2Uub3ZlcmRyYXc7XG5cblx0XHR0aGlzLnZpc2libGUgPSBzb3VyY2UudmlzaWJsZTtcblx0XHR0aGlzLmNsaXBTaGFkb3dzID0gc291cmNlLmNsaXBTaGFkb3dzO1xuXHRcdHRoaXMuY2xpcEludGVyc2VjdGlvbiA9IHNvdXJjZS5jbGlwSW50ZXJzZWN0aW9uO1xuXG5cdFx0dmFyIHNyY1BsYW5lcyA9IHNvdXJjZS5jbGlwcGluZ1BsYW5lcyxcblx0XHRcdGRzdFBsYW5lcyA9IG51bGw7XG5cblx0XHRpZiAoIHNyY1BsYW5lcyAhPT0gbnVsbCApIHtcblxuXHRcdFx0dmFyIG4gPSBzcmNQbGFuZXMubGVuZ3RoO1xuXHRcdFx0ZHN0UGxhbmVzID0gbmV3IEFycmF5KCBuICk7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gbjsgKysgaSApXG5cdFx0XHRcdGRzdFBsYW5lc1sgaSBdID0gc3JjUGxhbmVzWyBpIF0uY2xvbmUoKTtcblxuXHRcdH1cblxuXHRcdHRoaXMuY2xpcHBpbmdQbGFuZXMgPSBkc3RQbGFuZXM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGRpc3Bvc2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZGlzcGF0Y2hFdmVudCggeyB0eXBlOiAnZGlzcG9zZScgfSApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBkZWZpbmVzOiB7IFwibGFiZWxcIiA6IFwidmFsdWVcIiB9LFxuICogIHVuaWZvcm1zOiB7IFwicGFyYW1ldGVyMVwiOiB7IHZhbHVlOiAxLjAgfSwgXCJwYXJhbWV0ZXIyXCI6IHsgdmFsdWUyOiAyIH0gfSxcbiAqXG4gKiAgZnJhZ21lbnRTaGFkZXI6IDxzdHJpbmc+LFxuICogIHZlcnRleFNoYWRlcjogPHN0cmluZz4sXG4gKlxuICogIHdpcmVmcmFtZTogPGJvb2xlYW4+LFxuICogIHdpcmVmcmFtZUxpbmV3aWR0aDogPGZsb2F0PixcbiAqXG4gKiAgbGlnaHRzOiA8Ym9vbD4sXG4gKlxuICogIHNraW5uaW5nOiA8Ym9vbD4sXG4gKiAgbW9ycGhUYXJnZXRzOiA8Ym9vbD4sXG4gKiAgbW9ycGhOb3JtYWxzOiA8Ym9vbD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBTaGFkZXJNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1NoYWRlck1hdGVyaWFsJztcblxuXHR0aGlzLmRlZmluZXMgPSB7fTtcblx0dGhpcy51bmlmb3JtcyA9IHt9O1xuXG5cdHRoaXMudmVydGV4U2hhZGVyID0gJ3ZvaWQgbWFpbigpIHtcXG5cXHRnbF9Qb3NpdGlvbiA9IHByb2plY3Rpb25NYXRyaXggKiBtb2RlbFZpZXdNYXRyaXggKiB2ZWM0KCBwb3NpdGlvbiwgMS4wICk7XFxufSc7XG5cdHRoaXMuZnJhZ21lbnRTaGFkZXIgPSAndm9pZCBtYWluKCkge1xcblxcdGdsX0ZyYWdDb2xvciA9IHZlYzQoIDEuMCwgMC4wLCAwLjAsIDEuMCApO1xcbn0nO1xuXG5cdHRoaXMubGluZXdpZHRoID0gMTtcblxuXHR0aGlzLndpcmVmcmFtZSA9IGZhbHNlO1xuXHR0aGlzLndpcmVmcmFtZUxpbmV3aWR0aCA9IDE7XG5cblx0dGhpcy5mb2cgPSBmYWxzZTsgLy8gc2V0IHRvIHVzZSBzY2VuZSBmb2dcblx0dGhpcy5saWdodHMgPSBmYWxzZTsgLy8gc2V0IHRvIHVzZSBzY2VuZSBsaWdodHNcblx0dGhpcy5jbGlwcGluZyA9IGZhbHNlOyAvLyBzZXQgdG8gdXNlIHVzZXItZGVmaW5lZCBjbGlwcGluZyBwbGFuZXNcblxuXHR0aGlzLnNraW5uaW5nID0gZmFsc2U7IC8vIHNldCB0byB1c2Ugc2tpbm5pbmcgYXR0cmlidXRlIHN0cmVhbXNcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBmYWxzZTsgLy8gc2V0IHRvIHVzZSBtb3JwaCB0YXJnZXRzXG5cdHRoaXMubW9ycGhOb3JtYWxzID0gZmFsc2U7IC8vIHNldCB0byB1c2UgbW9ycGggbm9ybWFsc1xuXG5cdHRoaXMuZXh0ZW5zaW9ucyA9IHtcblx0XHRkZXJpdmF0aXZlczogZmFsc2UsIC8vIHNldCB0byB1c2UgZGVyaXZhdGl2ZXNcblx0XHRmcmFnRGVwdGg6IGZhbHNlLCAvLyBzZXQgdG8gdXNlIGZyYWdtZW50IGRlcHRoIHZhbHVlc1xuXHRcdGRyYXdCdWZmZXJzOiBmYWxzZSwgLy8gc2V0IHRvIHVzZSBkcmF3IGJ1ZmZlcnNcblx0XHRzaGFkZXJUZXh0dXJlTE9EOiBmYWxzZSAvLyBzZXQgdG8gdXNlIHNoYWRlciB0ZXh0dXJlIExPRFxuXHR9O1xuXG5cdC8vIFdoZW4gcmVuZGVyZWQgZ2VvbWV0cnkgZG9lc24ndCBpbmNsdWRlIHRoZXNlIGF0dHJpYnV0ZXMgYnV0IHRoZSBtYXRlcmlhbCBkb2VzLFxuXHQvLyB1c2UgdGhlc2UgZGVmYXVsdCB2YWx1ZXMgaW4gV2ViR0wuIFRoaXMgYXZvaWRzIGVycm9ycyB3aGVuIGJ1ZmZlciBkYXRhIGlzIG1pc3NpbmcuXG5cdHRoaXMuZGVmYXVsdEF0dHJpYnV0ZVZhbHVlcyA9IHtcblx0XHQnY29sb3InOiBbIDEsIDEsIDEgXSxcblx0XHQndXYnOiBbIDAsIDAgXSxcblx0XHQndXYyJzogWyAwLCAwIF1cblx0fTtcblxuXHR0aGlzLmluZGV4MEF0dHJpYnV0ZU5hbWUgPSB1bmRlZmluZWQ7XG5cblx0aWYgKCBwYXJhbWV0ZXJzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRpZiAoIHBhcmFtZXRlcnMuYXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuU2hhZGVyTWF0ZXJpYWw6IGF0dHJpYnV0ZXMgc2hvdWxkIG5vdyBiZSBkZWZpbmVkIGluIFRIUkVFLkJ1ZmZlckdlb21ldHJ5IGluc3RlYWQuJyApO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxuXHR9XG5cbn1cblxuU2hhZGVyTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWF0ZXJpYWwucHJvdG90eXBlICk7XG5TaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBTaGFkZXJNYXRlcmlhbDtcblxuU2hhZGVyTWF0ZXJpYWwucHJvdG90eXBlLmlzU2hhZGVyTWF0ZXJpYWwgPSB0cnVlO1xuXG5TaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuZnJhZ21lbnRTaGFkZXIgPSBzb3VyY2UuZnJhZ21lbnRTaGFkZXI7XG5cdHRoaXMudmVydGV4U2hhZGVyID0gc291cmNlLnZlcnRleFNoYWRlcjtcblxuXHR0aGlzLnVuaWZvcm1zID0gVW5pZm9ybXNVdGlscy5jbG9uZSggc291cmNlLnVuaWZvcm1zICk7XG5cblx0dGhpcy5kZWZpbmVzID0gc291cmNlLmRlZmluZXM7XG5cblx0dGhpcy53aXJlZnJhbWUgPSBzb3VyY2Uud2lyZWZyYW1lO1xuXHR0aGlzLndpcmVmcmFtZUxpbmV3aWR0aCA9IHNvdXJjZS53aXJlZnJhbWVMaW5ld2lkdGg7XG5cblx0dGhpcy5saWdodHMgPSBzb3VyY2UubGlnaHRzO1xuXHR0aGlzLmNsaXBwaW5nID0gc291cmNlLmNsaXBwaW5nO1xuXG5cdHRoaXMuc2tpbm5pbmcgPSBzb3VyY2Uuc2tpbm5pbmc7XG5cblx0dGhpcy5tb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXHR0aGlzLm1vcnBoTm9ybWFscyA9IHNvdXJjZS5tb3JwaE5vcm1hbHM7XG5cblx0dGhpcy5leHRlbnNpb25zID0gc291cmNlLmV4dGVuc2lvbnM7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cblNoYWRlck1hdGVyaWFsLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoIG1ldGEgKSB7XG5cblx0dmFyIGRhdGEgPSBNYXRlcmlhbC5wcm90b3R5cGUudG9KU09OLmNhbGwoIHRoaXMsIG1ldGEgKTtcblxuXHRkYXRhLnVuaWZvcm1zID0gdGhpcy51bmlmb3Jtcztcblx0ZGF0YS52ZXJ0ZXhTaGFkZXIgPSB0aGlzLnZlcnRleFNoYWRlcjtcblx0ZGF0YS5mcmFnbWVudFNoYWRlciA9IHRoaXMuZnJhZ21lbnRTaGFkZXI7XG5cblx0cmV0dXJuIGRhdGE7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cHM6Ly9jbGFyYS5pb1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqXG4gKiAgb3BhY2l0eTogPGZsb2F0PixcbiAqXG4gKiAgbWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBhbHBoYU1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKiAgZGlzcGxhY2VtZW50TWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGRpc3BsYWNlbWVudFNjYWxlOiA8ZmxvYXQ+LFxuICogIGRpc3BsYWNlbWVudEJpYXM6IDxmbG9hdD4sXG4gKlxuICogIHdpcmVmcmFtZTogPGJvb2xlYW4+LFxuICogIHdpcmVmcmFtZUxpbmV3aWR0aDogPGZsb2F0PlxuICogfVxuICovXG5cbmZ1bmN0aW9uIE1lc2hEZXB0aE1hdGVyaWFsKCBwYXJhbWV0ZXJzICkge1xuXG5cdE1hdGVyaWFsLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnTWVzaERlcHRoTWF0ZXJpYWwnO1xuXG5cdHRoaXMuZGVwdGhQYWNraW5nID0gQmFzaWNEZXB0aFBhY2tpbmc7XG5cblx0dGhpcy5za2lubmluZyA9IGZhbHNlO1xuXHR0aGlzLm1vcnBoVGFyZ2V0cyA9IGZhbHNlO1xuXG5cdHRoaXMubWFwID0gbnVsbDtcblxuXHR0aGlzLmFscGhhTWFwID0gbnVsbDtcblxuXHR0aGlzLmRpc3BsYWNlbWVudE1hcCA9IG51bGw7XG5cdHRoaXMuZGlzcGxhY2VtZW50U2NhbGUgPSAxO1xuXHR0aGlzLmRpc3BsYWNlbWVudEJpYXMgPSAwO1xuXG5cdHRoaXMud2lyZWZyYW1lID0gZmFsc2U7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gMTtcblxuXHR0aGlzLmZvZyA9IGZhbHNlO1xuXHR0aGlzLmxpZ2h0cyA9IGZhbHNlO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuTWVzaERlcHRoTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWF0ZXJpYWwucHJvdG90eXBlICk7XG5NZXNoRGVwdGhNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBNZXNoRGVwdGhNYXRlcmlhbDtcblxuTWVzaERlcHRoTWF0ZXJpYWwucHJvdG90eXBlLmlzTWVzaERlcHRoTWF0ZXJpYWwgPSB0cnVlO1xuXG5NZXNoRGVwdGhNYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuZGVwdGhQYWNraW5nID0gc291cmNlLmRlcHRoUGFja2luZztcblxuXHR0aGlzLnNraW5uaW5nID0gc291cmNlLnNraW5uaW5nO1xuXHR0aGlzLm1vcnBoVGFyZ2V0cyA9IHNvdXJjZS5tb3JwaFRhcmdldHM7XG5cblx0dGhpcy5tYXAgPSBzb3VyY2UubWFwO1xuXG5cdHRoaXMuYWxwaGFNYXAgPSBzb3VyY2UuYWxwaGFNYXA7XG5cblx0dGhpcy5kaXNwbGFjZW1lbnRNYXAgPSBzb3VyY2UuZGlzcGxhY2VtZW50TWFwO1xuXHR0aGlzLmRpc3BsYWNlbWVudFNjYWxlID0gc291cmNlLmRpc3BsYWNlbWVudFNjYWxlO1xuXHR0aGlzLmRpc3BsYWNlbWVudEJpYXMgPSBzb3VyY2UuZGlzcGxhY2VtZW50QmlhcztcblxuXHR0aGlzLndpcmVmcmFtZSA9IHNvdXJjZS53aXJlZnJhbWU7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gc291cmNlLndpcmVmcmFtZUxpbmV3aWR0aDtcblxuXHRyZXR1cm4gdGhpcztcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvXG4gKiBAYXV0aG9yIFdlc3RMYW5nbGV5IC8gaHR0cDovL2dpdGh1Yi5jb20vV2VzdExhbmdsZXlcbiAqL1xuXG5mdW5jdGlvbiBCb3gzKCBtaW4sIG1heCApIHtcblxuXHR0aGlzLm1pbiA9ICggbWluICE9PSB1bmRlZmluZWQgKSA/IG1pbiA6IG5ldyBWZWN0b3IzKCArIEluZmluaXR5LCArIEluZmluaXR5LCArIEluZmluaXR5ICk7XG5cdHRoaXMubWF4ID0gKCBtYXggIT09IHVuZGVmaW5lZCApID8gbWF4IDogbmV3IFZlY3RvcjMoIC0gSW5maW5pdHksIC0gSW5maW5pdHksIC0gSW5maW5pdHkgKTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBCb3gzLnByb3RvdHlwZSwge1xuXG5cdGlzQm94MzogdHJ1ZSxcblxuXHRzZXQ6IGZ1bmN0aW9uICggbWluLCBtYXggKSB7XG5cblx0XHR0aGlzLm1pbi5jb3B5KCBtaW4gKTtcblx0XHR0aGlzLm1heC5jb3B5KCBtYXggKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbUFycmF5OiBmdW5jdGlvbiAoIGFycmF5ICkge1xuXG5cdFx0dmFyIG1pblggPSArIEluZmluaXR5O1xuXHRcdHZhciBtaW5ZID0gKyBJbmZpbml0eTtcblx0XHR2YXIgbWluWiA9ICsgSW5maW5pdHk7XG5cblx0XHR2YXIgbWF4WCA9IC0gSW5maW5pdHk7XG5cdFx0dmFyIG1heFkgPSAtIEluZmluaXR5O1xuXHRcdHZhciBtYXhaID0gLSBJbmZpbml0eTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkgKz0gMyApIHtcblxuXHRcdFx0dmFyIHggPSBhcnJheVsgaSBdO1xuXHRcdFx0dmFyIHkgPSBhcnJheVsgaSArIDEgXTtcblx0XHRcdHZhciB6ID0gYXJyYXlbIGkgKyAyIF07XG5cblx0XHRcdGlmICggeCA8IG1pblggKSBtaW5YID0geDtcblx0XHRcdGlmICggeSA8IG1pblkgKSBtaW5ZID0geTtcblx0XHRcdGlmICggeiA8IG1pblogKSBtaW5aID0gejtcblxuXHRcdFx0aWYgKCB4ID4gbWF4WCApIG1heFggPSB4O1xuXHRcdFx0aWYgKCB5ID4gbWF4WSApIG1heFkgPSB5O1xuXHRcdFx0aWYgKCB6ID4gbWF4WiApIG1heFogPSB6O1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5taW4uc2V0KCBtaW5YLCBtaW5ZLCBtaW5aICk7XG5cdFx0dGhpcy5tYXguc2V0KCBtYXhYLCBtYXhZLCBtYXhaICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21CdWZmZXJBdHRyaWJ1dGU6IGZ1bmN0aW9uICggYXR0cmlidXRlICkge1xuXG5cdFx0dmFyIG1pblggPSArIEluZmluaXR5O1xuXHRcdHZhciBtaW5ZID0gKyBJbmZpbml0eTtcblx0XHR2YXIgbWluWiA9ICsgSW5maW5pdHk7XG5cblx0XHR2YXIgbWF4WCA9IC0gSW5maW5pdHk7XG5cdFx0dmFyIG1heFkgPSAtIEluZmluaXR5O1xuXHRcdHZhciBtYXhaID0gLSBJbmZpbml0eTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGF0dHJpYnV0ZS5jb3VudDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciB4ID0gYXR0cmlidXRlLmdldFgoIGkgKTtcblx0XHRcdHZhciB5ID0gYXR0cmlidXRlLmdldFkoIGkgKTtcblx0XHRcdHZhciB6ID0gYXR0cmlidXRlLmdldFooIGkgKTtcblxuXHRcdFx0aWYgKCB4IDwgbWluWCApIG1pblggPSB4O1xuXHRcdFx0aWYgKCB5IDwgbWluWSApIG1pblkgPSB5O1xuXHRcdFx0aWYgKCB6IDwgbWluWiApIG1pblogPSB6O1xuXG5cdFx0XHRpZiAoIHggPiBtYXhYICkgbWF4WCA9IHg7XG5cdFx0XHRpZiAoIHkgPiBtYXhZICkgbWF4WSA9IHk7XG5cdFx0XHRpZiAoIHogPiBtYXhaICkgbWF4WiA9IHo7XG5cblx0XHR9XG5cblx0XHR0aGlzLm1pbi5zZXQoIG1pblgsIG1pblksIG1pblogKTtcblx0XHR0aGlzLm1heC5zZXQoIG1heFgsIG1heFksIG1heFogKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbVBvaW50czogZnVuY3Rpb24gKCBwb2ludHMgKSB7XG5cblx0XHR0aGlzLm1ha2VFbXB0eSgpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0dGhpcy5leHBhbmRCeVBvaW50KCBwb2ludHNbIGkgXSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tQ2VudGVyQW5kU2l6ZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBzZXRGcm9tQ2VudGVyQW5kU2l6ZSggY2VudGVyLCBzaXplICkge1xuXG5cdFx0XHR2YXIgaGFsZlNpemUgPSB2MS5jb3B5KCBzaXplICkubXVsdGlwbHlTY2FsYXIoIDAuNSApO1xuXG5cdFx0XHR0aGlzLm1pbi5jb3B5KCBjZW50ZXIgKS5zdWIoIGhhbGZTaXplICk7XG5cdFx0XHR0aGlzLm1heC5jb3B5KCBjZW50ZXIgKS5hZGQoIGhhbGZTaXplICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0c2V0RnJvbU9iamVjdDogZnVuY3Rpb24gKCBvYmplY3QgKSB7XG5cblx0XHR0aGlzLm1ha2VFbXB0eSgpO1xuXG5cdFx0cmV0dXJuIHRoaXMuZXhwYW5kQnlPYmplY3QoIG9iamVjdCApO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggYm94ICkge1xuXG5cdFx0dGhpcy5taW4uY29weSggYm94Lm1pbiApO1xuXHRcdHRoaXMubWF4LmNvcHkoIGJveC5tYXggKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bWFrZUVtcHR5OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLm1pbi54ID0gdGhpcy5taW4ueSA9IHRoaXMubWluLnogPSArIEluZmluaXR5O1xuXHRcdHRoaXMubWF4LnggPSB0aGlzLm1heC55ID0gdGhpcy5tYXgueiA9IC0gSW5maW5pdHk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGlzRW1wdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIHRoaXMgaXMgYSBtb3JlIHJvYnVzdCBjaGVjayBmb3IgZW1wdHkgdGhhbiAoIHZvbHVtZSA8PSAwICkgYmVjYXVzZSB2b2x1bWUgY2FuIGdldCBwb3NpdGl2ZSB3aXRoIHR3byBuZWdhdGl2ZSBheGVzXG5cblx0XHRyZXR1cm4gKCB0aGlzLm1heC54IDwgdGhpcy5taW4ueCApIHx8ICggdGhpcy5tYXgueSA8IHRoaXMubWluLnkgKSB8fCAoIHRoaXMubWF4LnogPCB0aGlzLm1pbi56ICk7XG5cblx0fSxcblxuXHRnZXRDZW50ZXI6IGZ1bmN0aW9uICggb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjMoKTtcblx0XHRyZXR1cm4gdGhpcy5pc0VtcHR5KCkgPyByZXN1bHQuc2V0KCAwLCAwLCAwICkgOiByZXN1bHQuYWRkVmVjdG9ycyggdGhpcy5taW4sIHRoaXMubWF4ICkubXVsdGlwbHlTY2FsYXIoIDAuNSApO1xuXG5cdH0sXG5cblx0Z2V0U2l6ZTogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdHJldHVybiB0aGlzLmlzRW1wdHkoKSA/IHJlc3VsdC5zZXQoIDAsIDAsIDAgKSA6IHJlc3VsdC5zdWJWZWN0b3JzKCB0aGlzLm1heCwgdGhpcy5taW4gKTtcblxuXHR9LFxuXG5cdGV4cGFuZEJ5UG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQgKSB7XG5cblx0XHR0aGlzLm1pbi5taW4oIHBvaW50ICk7XG5cdFx0dGhpcy5tYXgubWF4KCBwb2ludCApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRleHBhbmRCeVZlY3RvcjogZnVuY3Rpb24gKCB2ZWN0b3IgKSB7XG5cblx0XHR0aGlzLm1pbi5zdWIoIHZlY3RvciApO1xuXHRcdHRoaXMubWF4LmFkZCggdmVjdG9yICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGV4cGFuZEJ5U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcblxuXHRcdHRoaXMubWluLmFkZFNjYWxhciggLSBzY2FsYXIgKTtcblx0XHR0aGlzLm1heC5hZGRTY2FsYXIoIHNjYWxhciApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRleHBhbmRCeU9iamVjdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gQ29tcHV0ZXMgdGhlIHdvcmxkLWF4aXMtYWxpZ25lZCBib3VuZGluZyBib3ggb2YgYW4gb2JqZWN0IChpbmNsdWRpbmcgaXRzIGNoaWxkcmVuKSxcblx0XHQvLyBhY2NvdW50aW5nIGZvciBib3RoIHRoZSBvYmplY3QncywgYW5kIGNoaWxkcmVuJ3MsIHdvcmxkIHRyYW5zZm9ybXNcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZXhwYW5kQnlPYmplY3QoIG9iamVjdCApIHtcblxuXHRcdFx0dmFyIHNjb3BlID0gdGhpcztcblxuXHRcdFx0b2JqZWN0LnVwZGF0ZU1hdHJpeFdvcmxkKCB0cnVlICk7XG5cblx0XHRcdG9iamVjdC50cmF2ZXJzZSggZnVuY3Rpb24gKCBub2RlICkge1xuXG5cdFx0XHRcdHZhciBpLCBsO1xuXG5cdFx0XHRcdHZhciBnZW9tZXRyeSA9IG5vZGUuZ2VvbWV0cnk7XG5cblx0XHRcdFx0aWYgKCBnZW9tZXRyeSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0aWYgKCBnZW9tZXRyeS5pc0dlb21ldHJ5ICkge1xuXG5cdFx0XHRcdFx0XHR2YXIgdmVydGljZXMgPSBnZW9tZXRyeS52ZXJ0aWNlcztcblxuXHRcdFx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSB2ZXJ0aWNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdHYxLmNvcHkoIHZlcnRpY2VzWyBpIF0gKTtcblx0XHRcdFx0XHRcdFx0djEuYXBwbHlNYXRyaXg0KCBub2RlLm1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0XHRcdFx0c2NvcGUuZXhwYW5kQnlQb2ludCggdjEgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fSBlbHNlIGlmICggZ2VvbWV0cnkuaXNCdWZmZXJHZW9tZXRyeSApIHtcblxuXHRcdFx0XHRcdFx0dmFyIGF0dHJpYnV0ZSA9IGdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cblx0XHRcdFx0XHRcdGlmICggYXR0cmlidXRlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBhdHRyaWJ1dGUuY291bnQ7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0djEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggYXR0cmlidXRlLCBpICkuYXBwbHlNYXRyaXg0KCBub2RlLm1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0XHRcdFx0XHRzY29wZS5leHBhbmRCeVBvaW50KCB2MSApO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGNvbnRhaW5zUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQgKSB7XG5cblx0XHRyZXR1cm4gcG9pbnQueCA8IHRoaXMubWluLnggfHwgcG9pbnQueCA+IHRoaXMubWF4LnggfHxcblx0XHRcdHBvaW50LnkgPCB0aGlzLm1pbi55IHx8IHBvaW50LnkgPiB0aGlzLm1heC55IHx8XG5cdFx0XHRwb2ludC56IDwgdGhpcy5taW4ueiB8fCBwb2ludC56ID4gdGhpcy5tYXgueiA/IGZhbHNlIDogdHJ1ZTtcblxuXHR9LFxuXG5cdGNvbnRhaW5zQm94OiBmdW5jdGlvbiAoIGJveCApIHtcblxuXHRcdHJldHVybiB0aGlzLm1pbi54IDw9IGJveC5taW4ueCAmJiBib3gubWF4LnggPD0gdGhpcy5tYXgueCAmJlxuXHRcdFx0dGhpcy5taW4ueSA8PSBib3gubWluLnkgJiYgYm94Lm1heC55IDw9IHRoaXMubWF4LnkgJiZcblx0XHRcdHRoaXMubWluLnogPD0gYm94Lm1pbi56ICYmIGJveC5tYXgueiA8PSB0aGlzLm1heC56O1xuXG5cdH0sXG5cblx0Z2V0UGFyYW1ldGVyOiBmdW5jdGlvbiAoIHBvaW50LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdC8vIFRoaXMgY2FuIHBvdGVudGlhbGx5IGhhdmUgYSBkaXZpZGUgYnkgemVybyBpZiB0aGUgYm94XG5cdFx0Ly8gaGFzIGEgc2l6ZSBkaW1lbnNpb24gb2YgMC5cblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIHJlc3VsdC5zZXQoXG5cdFx0XHQoIHBvaW50LnggLSB0aGlzLm1pbi54ICkgLyAoIHRoaXMubWF4LnggLSB0aGlzLm1pbi54ICksXG5cdFx0XHQoIHBvaW50LnkgLSB0aGlzLm1pbi55ICkgLyAoIHRoaXMubWF4LnkgLSB0aGlzLm1pbi55ICksXG5cdFx0XHQoIHBvaW50LnogLSB0aGlzLm1pbi56ICkgLyAoIHRoaXMubWF4LnogLSB0aGlzLm1pbi56IClcblx0XHQpO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0c0JveDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHQvLyB1c2luZyA2IHNwbGl0dGluZyBwbGFuZXMgdG8gcnVsZSBvdXQgaW50ZXJzZWN0aW9ucy5cblx0XHRyZXR1cm4gYm94Lm1heC54IDwgdGhpcy5taW4ueCB8fCBib3gubWluLnggPiB0aGlzLm1heC54IHx8XG5cdFx0XHRib3gubWF4LnkgPCB0aGlzLm1pbi55IHx8IGJveC5taW4ueSA+IHRoaXMubWF4LnkgfHxcblx0XHRcdGJveC5tYXgueiA8IHRoaXMubWluLnogfHwgYm94Lm1pbi56ID4gdGhpcy5tYXgueiA/IGZhbHNlIDogdHJ1ZTtcblxuXHR9LFxuXG5cdGludGVyc2VjdHNTcGhlcmU6ICggZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGNsb3Nlc3RQb2ludCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gaW50ZXJzZWN0c1NwaGVyZSggc3BoZXJlICkge1xuXG5cdFx0XHQvLyBGaW5kIHRoZSBwb2ludCBvbiB0aGUgQUFCQiBjbG9zZXN0IHRvIHRoZSBzcGhlcmUgY2VudGVyLlxuXHRcdFx0dGhpcy5jbGFtcFBvaW50KCBzcGhlcmUuY2VudGVyLCBjbG9zZXN0UG9pbnQgKTtcblxuXHRcdFx0Ly8gSWYgdGhhdCBwb2ludCBpcyBpbnNpZGUgdGhlIHNwaGVyZSwgdGhlIEFBQkIgYW5kIHNwaGVyZSBpbnRlcnNlY3QuXG5cdFx0XHRyZXR1cm4gY2xvc2VzdFBvaW50LmRpc3RhbmNlVG9TcXVhcmVkKCBzcGhlcmUuY2VudGVyICkgPD0gKCBzcGhlcmUucmFkaXVzICogc3BoZXJlLnJhZGl1cyApO1xuXG5cdFx0fTtcblxuXHR9ICkoKSxcblxuXHRpbnRlcnNlY3RzUGxhbmU6IGZ1bmN0aW9uICggcGxhbmUgKSB7XG5cblx0XHQvLyBXZSBjb21wdXRlIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGRvdCBwcm9kdWN0IHZhbHVlcy4gSWYgdGhvc2UgdmFsdWVzXG5cdFx0Ly8gYXJlIG9uIHRoZSBzYW1lIHNpZGUgKGJhY2sgb3IgZnJvbnQpIG9mIHRoZSBwbGFuZSwgdGhlbiB0aGVyZSBpcyBubyBpbnRlcnNlY3Rpb24uXG5cblx0XHR2YXIgbWluLCBtYXg7XG5cblx0XHRpZiAoIHBsYW5lLm5vcm1hbC54ID4gMCApIHtcblxuXHRcdFx0bWluID0gcGxhbmUubm9ybWFsLnggKiB0aGlzLm1pbi54O1xuXHRcdFx0bWF4ID0gcGxhbmUubm9ybWFsLnggKiB0aGlzLm1heC54O1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0bWluID0gcGxhbmUubm9ybWFsLnggKiB0aGlzLm1heC54O1xuXHRcdFx0bWF4ID0gcGxhbmUubm9ybWFsLnggKiB0aGlzLm1pbi54O1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBwbGFuZS5ub3JtYWwueSA+IDAgKSB7XG5cblx0XHRcdG1pbiArPSBwbGFuZS5ub3JtYWwueSAqIHRoaXMubWluLnk7XG5cdFx0XHRtYXggKz0gcGxhbmUubm9ybWFsLnkgKiB0aGlzLm1heC55O1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0bWluICs9IHBsYW5lLm5vcm1hbC55ICogdGhpcy5tYXgueTtcblx0XHRcdG1heCArPSBwbGFuZS5ub3JtYWwueSAqIHRoaXMubWluLnk7XG5cblx0XHR9XG5cblx0XHRpZiAoIHBsYW5lLm5vcm1hbC56ID4gMCApIHtcblxuXHRcdFx0bWluICs9IHBsYW5lLm5vcm1hbC56ICogdGhpcy5taW4uejtcblx0XHRcdG1heCArPSBwbGFuZS5ub3JtYWwueiAqIHRoaXMubWF4Lno7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRtaW4gKz0gcGxhbmUubm9ybWFsLnogKiB0aGlzLm1heC56O1xuXHRcdFx0bWF4ICs9IHBsYW5lLm5vcm1hbC56ICogdGhpcy5taW4uejtcblxuXHRcdH1cblxuXHRcdHJldHVybiAoIG1pbiA8PSBwbGFuZS5jb25zdGFudCAmJiBtYXggPj0gcGxhbmUuY29uc3RhbnQgKTtcblxuXHR9LFxuXG5cdGNsYW1wUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cdFx0cmV0dXJuIHJlc3VsdC5jb3B5KCBwb2ludCApLmNsYW1wKCB0aGlzLm1pbiwgdGhpcy5tYXggKTtcblxuXHR9LFxuXG5cdGRpc3RhbmNlVG9Qb2ludDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBkaXN0YW5jZVRvUG9pbnQoIHBvaW50ICkge1xuXG5cdFx0XHR2YXIgY2xhbXBlZFBvaW50ID0gdjEuY29weSggcG9pbnQgKS5jbGFtcCggdGhpcy5taW4sIHRoaXMubWF4ICk7XG5cdFx0XHRyZXR1cm4gY2xhbXBlZFBvaW50LnN1YiggcG9pbnQgKS5sZW5ndGgoKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGdldEJvdW5kaW5nU3BoZXJlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGdldEJvdW5kaW5nU3BoZXJlKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBTcGhlcmUoKTtcblxuXHRcdFx0dGhpcy5nZXRDZW50ZXIoIHJlc3VsdC5jZW50ZXIgKTtcblxuXHRcdFx0cmVzdWx0LnJhZGl1cyA9IHRoaXMuZ2V0U2l6ZSggdjEgKS5sZW5ndGgoKSAqIDAuNTtcblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGludGVyc2VjdDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHR0aGlzLm1pbi5tYXgoIGJveC5taW4gKTtcblx0XHR0aGlzLm1heC5taW4oIGJveC5tYXggKTtcblxuXHRcdC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIG5vIG92ZXJsYXAsIHRoZSByZXN1bHQgaXMgZnVsbHkgZW1wdHksIG5vdCBzbGlnaHRseSBlbXB0eSB3aXRoIG5vbi1pbmYvK2luZiB2YWx1ZXMgdGhhdCB3aWxsIGNhdXNlIHN1YnNlcXVlbmNlIGludGVyc2VjdHMgdG8gZXJyb25lb3VzbHkgcmV0dXJuIHZhbGlkIHZhbHVlcy5cblx0XHRpZiggdGhpcy5pc0VtcHR5KCkgKSB0aGlzLm1ha2VFbXB0eSgpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR1bmlvbjogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHR0aGlzLm1pbi5taW4oIGJveC5taW4gKTtcblx0XHR0aGlzLm1heC5tYXgoIGJveC5tYXggKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YXBwbHlNYXRyaXg0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcG9pbnRzID0gW1xuXHRcdFx0bmV3IFZlY3RvcjMoKSxcblx0XHRcdG5ldyBWZWN0b3IzKCksXG5cdFx0XHRuZXcgVmVjdG9yMygpLFxuXHRcdFx0bmV3IFZlY3RvcjMoKSxcblx0XHRcdG5ldyBWZWN0b3IzKCksXG5cdFx0XHRuZXcgVmVjdG9yMygpLFxuXHRcdFx0bmV3IFZlY3RvcjMoKSxcblx0XHRcdG5ldyBWZWN0b3IzKClcblx0XHRdO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGFwcGx5TWF0cml4NCggbWF0cml4ICkge1xuXG5cdFx0XHQvLyB0cmFuc2Zvcm0gb2YgZW1wdHkgYm94IGlzIGFuIGVtcHR5IGJveC5cblx0XHRcdGlmKCB0aGlzLmlzRW1wdHkoKSApIHJldHVybiB0aGlzO1xuXG5cdFx0XHQvLyBOT1RFOiBJIGFtIHVzaW5nIGEgYmluYXJ5IHBhdHRlcm4gdG8gc3BlY2lmeSBhbGwgMl4zIGNvbWJpbmF0aW9ucyBiZWxvd1xuXHRcdFx0cG9pbnRzWyAwIF0uc2V0KCB0aGlzLm1pbi54LCB0aGlzLm1pbi55LCB0aGlzLm1pbi56ICkuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTsgLy8gMDAwXG5cdFx0XHRwb2ludHNbIDEgXS5zZXQoIHRoaXMubWluLngsIHRoaXMubWluLnksIHRoaXMubWF4LnogKS5hcHBseU1hdHJpeDQoIG1hdHJpeCApOyAvLyAwMDFcblx0XHRcdHBvaW50c1sgMiBdLnNldCggdGhpcy5taW4ueCwgdGhpcy5tYXgueSwgdGhpcy5taW4ueiApLmFwcGx5TWF0cml4NCggbWF0cml4ICk7IC8vIDAxMFxuXHRcdFx0cG9pbnRzWyAzIF0uc2V0KCB0aGlzLm1pbi54LCB0aGlzLm1heC55LCB0aGlzLm1heC56ICkuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTsgLy8gMDExXG5cdFx0XHRwb2ludHNbIDQgXS5zZXQoIHRoaXMubWF4LngsIHRoaXMubWluLnksIHRoaXMubWluLnogKS5hcHBseU1hdHJpeDQoIG1hdHJpeCApOyAvLyAxMDBcblx0XHRcdHBvaW50c1sgNSBdLnNldCggdGhpcy5tYXgueCwgdGhpcy5taW4ueSwgdGhpcy5tYXgueiApLmFwcGx5TWF0cml4NCggbWF0cml4ICk7IC8vIDEwMVxuXHRcdFx0cG9pbnRzWyA2IF0uc2V0KCB0aGlzLm1heC54LCB0aGlzLm1heC55LCB0aGlzLm1pbi56ICkuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTsgLy8gMTEwXG5cdFx0XHRwb2ludHNbIDcgXS5zZXQoIHRoaXMubWF4LngsIHRoaXMubWF4LnksIHRoaXMubWF4LnogKS5hcHBseU1hdHJpeDQoIG1hdHJpeCApO1x0Ly8gMTExXG5cblx0XHRcdHRoaXMuc2V0RnJvbVBvaW50cyggcG9pbnRzICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoIG9mZnNldCApIHtcblxuXHRcdHRoaXMubWluLmFkZCggb2Zmc2V0ICk7XG5cdFx0dGhpcy5tYXguYWRkKCBvZmZzZXQgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIGJveCApIHtcblxuXHRcdHJldHVybiBib3gubWluLmVxdWFscyggdGhpcy5taW4gKSAmJiBib3gubWF4LmVxdWFscyggdGhpcy5tYXggKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFNwaGVyZSggY2VudGVyLCByYWRpdXMgKSB7XG5cblx0dGhpcy5jZW50ZXIgPSAoIGNlbnRlciAhPT0gdW5kZWZpbmVkICkgPyBjZW50ZXIgOiBuZXcgVmVjdG9yMygpO1xuXHR0aGlzLnJhZGl1cyA9ICggcmFkaXVzICE9PSB1bmRlZmluZWQgKSA/IHJhZGl1cyA6IDA7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggU3BoZXJlLnByb3RvdHlwZSwge1xuXG5cdHNldDogZnVuY3Rpb24gKCBjZW50ZXIsIHJhZGl1cyApIHtcblxuXHRcdHRoaXMuY2VudGVyLmNvcHkoIGNlbnRlciApO1xuXHRcdHRoaXMucmFkaXVzID0gcmFkaXVzO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tUG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYm94ID0gbmV3IEJveDMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBzZXRGcm9tUG9pbnRzKCBwb2ludHMsIG9wdGlvbmFsQ2VudGVyICkge1xuXG5cdFx0XHR2YXIgY2VudGVyID0gdGhpcy5jZW50ZXI7XG5cblx0XHRcdGlmICggb3B0aW9uYWxDZW50ZXIgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjZW50ZXIuY29weSggb3B0aW9uYWxDZW50ZXIgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRib3guc2V0RnJvbVBvaW50cyggcG9pbnRzICkuZ2V0Q2VudGVyKCBjZW50ZXIgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbWF4UmFkaXVzU3EgPSAwO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHRcdG1heFJhZGl1c1NxID0gTWF0aC5tYXgoIG1heFJhZGl1c1NxLCBjZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQoIHBvaW50c1sgaSBdICkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnJhZGl1cyA9IE1hdGguc3FydCggbWF4UmFkaXVzU3EgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzcGhlcmUgKSB7XG5cblx0XHR0aGlzLmNlbnRlci5jb3B5KCBzcGhlcmUuY2VudGVyICk7XG5cdFx0dGhpcy5yYWRpdXMgPSBzcGhlcmUucmFkaXVzO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuICggdGhpcy5yYWRpdXMgPD0gMCApO1xuXG5cdH0sXG5cblx0Y29udGFpbnNQb2ludDogZnVuY3Rpb24gKCBwb2ludCApIHtcblxuXHRcdHJldHVybiAoIHBvaW50LmRpc3RhbmNlVG9TcXVhcmVkKCB0aGlzLmNlbnRlciApIDw9ICggdGhpcy5yYWRpdXMgKiB0aGlzLnJhZGl1cyApICk7XG5cblx0fSxcblxuXHRkaXN0YW5jZVRvUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQgKSB7XG5cblx0XHRyZXR1cm4gKCBwb2ludC5kaXN0YW5jZVRvKCB0aGlzLmNlbnRlciApIC0gdGhpcy5yYWRpdXMgKTtcblxuXHR9LFxuXG5cdGludGVyc2VjdHNTcGhlcmU6IGZ1bmN0aW9uICggc3BoZXJlICkge1xuXG5cdFx0dmFyIHJhZGl1c1N1bSA9IHRoaXMucmFkaXVzICsgc3BoZXJlLnJhZGl1cztcblxuXHRcdHJldHVybiBzcGhlcmUuY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKCB0aGlzLmNlbnRlciApIDw9ICggcmFkaXVzU3VtICogcmFkaXVzU3VtICk7XG5cblx0fSxcblxuXHRpbnRlcnNlY3RzQm94OiBmdW5jdGlvbiAoIGJveCApIHtcblxuXHRcdHJldHVybiBib3guaW50ZXJzZWN0c1NwaGVyZSggdGhpcyApO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0c1BsYW5lOiBmdW5jdGlvbiAoIHBsYW5lICkge1xuXG5cdFx0Ly8gV2UgdXNlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb24gdG8gY29tcHV0ZSB0aGUgc2lnbmVkIGRpc3RhbmNlIGZyb21cblx0XHQvLyB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUgdG8gdGhlIHBsYW5lLlxuXHRcdC8vXG5cdFx0Ly8gZGlzdGFuY2UgPSBxICogbiAtIGRcblx0XHQvL1xuXHRcdC8vIElmIHRoaXMgZGlzdGFuY2UgaXMgZ3JlYXRlciB0aGFuIHRoZSByYWRpdXMgb2YgdGhlIHNwaGVyZSxcblx0XHQvLyB0aGVuIHRoZXJlIGlzIG5vIGludGVyc2VjdGlvbi5cblxuXHRcdHJldHVybiBNYXRoLmFicyggdGhpcy5jZW50ZXIuZG90KCBwbGFuZS5ub3JtYWwgKSAtIHBsYW5lLmNvbnN0YW50ICkgPD0gdGhpcy5yYWRpdXM7XG5cblx0fSxcblxuXHRjbGFtcFBvaW50OiBmdW5jdGlvbiAoIHBvaW50LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciBkZWx0YUxlbmd0aFNxID0gdGhpcy5jZW50ZXIuZGlzdGFuY2VUb1NxdWFyZWQoIHBvaW50ICk7XG5cblx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJlc3VsdC5jb3B5KCBwb2ludCApO1xuXG5cdFx0aWYgKCBkZWx0YUxlbmd0aFNxID4gKCB0aGlzLnJhZGl1cyAqIHRoaXMucmFkaXVzICkgKSB7XG5cblx0XHRcdHJlc3VsdC5zdWIoIHRoaXMuY2VudGVyICkubm9ybWFsaXplKCk7XG5cdFx0XHRyZXN1bHQubXVsdGlwbHlTY2FsYXIoIHRoaXMucmFkaXVzICkuYWRkKCB0aGlzLmNlbnRlciApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblxuXHR9LFxuXG5cdGdldEJvdW5kaW5nQm94OiBmdW5jdGlvbiAoIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIGJveCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBCb3gzKCk7XG5cblx0XHRib3guc2V0KCB0aGlzLmNlbnRlciwgdGhpcy5jZW50ZXIgKTtcblx0XHRib3guZXhwYW5kQnlTY2FsYXIoIHRoaXMucmFkaXVzICk7XG5cblx0XHRyZXR1cm4gYm94O1xuXG5cdH0sXG5cblx0YXBwbHlNYXRyaXg0OiBmdW5jdGlvbiAoIG1hdHJpeCApIHtcblxuXHRcdHRoaXMuY2VudGVyLmFwcGx5TWF0cml4NCggbWF0cml4ICk7XG5cdFx0dGhpcy5yYWRpdXMgPSB0aGlzLnJhZGl1cyAqIG1hdHJpeC5nZXRNYXhTY2FsZU9uQXhpcygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR0cmFuc2xhdGU6IGZ1bmN0aW9uICggb2Zmc2V0ICkge1xuXG5cdFx0dGhpcy5jZW50ZXIuYWRkKCBvZmZzZXQgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIHNwaGVyZSApIHtcblxuXHRcdHJldHVybiBzcGhlcmUuY2VudGVyLmVxdWFscyggdGhpcy5jZW50ZXIgKSAmJiAoIHNwaGVyZS5yYWRpdXMgPT09IHRoaXMucmFkaXVzICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICogQGF1dGhvciB0c2Nod1xuICovXG5cbmZ1bmN0aW9uIE1hdHJpeDMoKSB7XG5cblx0dGhpcy5lbGVtZW50cyA9IFtcblxuXHRcdDEsIDAsIDAsXG5cdFx0MCwgMSwgMCxcblx0XHQwLCAwLCAxXG5cblx0XTtcblxuXHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPiAwICkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLk1hdHJpeDM6IHRoZSBjb25zdHJ1Y3RvciBubyBsb25nZXIgcmVhZHMgYXJndW1lbnRzLiB1c2UgLnNldCgpIGluc3RlYWQuJyApO1xuXG5cdH1cblxufVxuXG5PYmplY3QuYXNzaWduKCBNYXRyaXgzLnByb3RvdHlwZSwge1xuXG5cdGlzTWF0cml4MzogdHJ1ZSxcblxuXHRzZXQ6IGZ1bmN0aW9uICggbjExLCBuMTIsIG4xMywgbjIxLCBuMjIsIG4yMywgbjMxLCBuMzIsIG4zMyApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR0ZVsgMCBdID0gbjExOyB0ZVsgMSBdID0gbjIxOyB0ZVsgMiBdID0gbjMxO1xuXHRcdHRlWyAzIF0gPSBuMTI7IHRlWyA0IF0gPSBuMjI7IHRlWyA1IF0gPSBuMzI7XG5cdFx0dGVbIDYgXSA9IG4xMzsgdGVbIDcgXSA9IG4yMzsgdGVbIDggXSA9IG4zMztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0aWRlbnRpdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHQxLCAwLCAwLFxuXHRcdFx0MCwgMSwgMCxcblx0XHRcdDAsIDAsIDFcblxuXHRcdCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5mcm9tQXJyYXkoIHRoaXMuZWxlbWVudHMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cdFx0dmFyIG1lID0gbS5lbGVtZW50cztcblxuXHRcdHRlWyAwIF0gPSBtZVsgMCBdOyB0ZVsgMSBdID0gbWVbIDEgXTsgdGVbIDIgXSA9IG1lWyAyIF07XG5cdFx0dGVbIDMgXSA9IG1lWyAzIF07IHRlWyA0IF0gPSBtZVsgNCBdOyB0ZVsgNSBdID0gbWVbIDUgXTtcblx0XHR0ZVsgNiBdID0gbWVbIDYgXTsgdGVbIDcgXSA9IG1lWyA3IF07IHRlWyA4IF0gPSBtZVsgOCBdO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tTWF0cml4NDogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0dmFyIG1lID0gbS5lbGVtZW50cztcblxuXHRcdHRoaXMuc2V0KFxuXG5cdFx0XHRtZVsgMCBdLCBtZVsgNCBdLCBtZVsgIDggXSxcblx0XHRcdG1lWyAxIF0sIG1lWyA1IF0sIG1lWyAgOSBdLFxuXHRcdFx0bWVbIDIgXSwgbWVbIDYgXSwgbWVbIDEwIF1cblxuXHRcdCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGFwcGx5VG9CdWZmZXJBdHRyaWJ1dGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gYXBwbHlUb0J1ZmZlckF0dHJpYnV0ZSggYXR0cmlidXRlICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBhdHRyaWJ1dGUuY291bnQ7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdHYxLnggPSBhdHRyaWJ1dGUuZ2V0WCggaSApO1xuXHRcdFx0XHR2MS55ID0gYXR0cmlidXRlLmdldFkoIGkgKTtcblx0XHRcdFx0djEueiA9IGF0dHJpYnV0ZS5nZXRaKCBpICk7XG5cblx0XHRcdFx0djEuYXBwbHlNYXRyaXgzKCB0aGlzICk7XG5cblx0XHRcdFx0YXR0cmlidXRlLnNldFhZWiggaSwgdjEueCwgdjEueSwgdjEueiApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBhdHRyaWJ1dGU7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRtdWx0aXBseTogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0cmV0dXJuIHRoaXMubXVsdGlwbHlNYXRyaWNlcyggdGhpcywgbSApO1xuXG5cdH0sXG5cblx0cHJlbXVsdGlwbHk6IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdHJldHVybiB0aGlzLm11bHRpcGx5TWF0cmljZXMoIG0sIHRoaXMgKTtcblxuXHR9LFxuXG5cdG11bHRpcGx5TWF0cmljZXM6IGZ1bmN0aW9uICggYSwgYiApIHtcblxuXHRcdHZhciBhZSA9IGEuZWxlbWVudHM7XG5cdFx0dmFyIGJlID0gYi5lbGVtZW50cztcblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0dmFyIGExMSA9IGFlWyAwIF0sIGExMiA9IGFlWyAzIF0sIGExMyA9IGFlWyA2IF07XG5cdFx0dmFyIGEyMSA9IGFlWyAxIF0sIGEyMiA9IGFlWyA0IF0sIGEyMyA9IGFlWyA3IF07XG5cdFx0dmFyIGEzMSA9IGFlWyAyIF0sIGEzMiA9IGFlWyA1IF0sIGEzMyA9IGFlWyA4IF07XG5cblx0XHR2YXIgYjExID0gYmVbIDAgXSwgYjEyID0gYmVbIDMgXSwgYjEzID0gYmVbIDYgXTtcblx0XHR2YXIgYjIxID0gYmVbIDEgXSwgYjIyID0gYmVbIDQgXSwgYjIzID0gYmVbIDcgXTtcblx0XHR2YXIgYjMxID0gYmVbIDIgXSwgYjMyID0gYmVbIDUgXSwgYjMzID0gYmVbIDggXTtcblxuXHRcdHRlWyAwIF0gPSBhMTEgKiBiMTEgKyBhMTIgKiBiMjEgKyBhMTMgKiBiMzE7XG5cdFx0dGVbIDMgXSA9IGExMSAqIGIxMiArIGExMiAqIGIyMiArIGExMyAqIGIzMjtcblx0XHR0ZVsgNiBdID0gYTExICogYjEzICsgYTEyICogYjIzICsgYTEzICogYjMzO1xuXG5cdFx0dGVbIDEgXSA9IGEyMSAqIGIxMSArIGEyMiAqIGIyMSArIGEyMyAqIGIzMTtcblx0XHR0ZVsgNCBdID0gYTIxICogYjEyICsgYTIyICogYjIyICsgYTIzICogYjMyO1xuXHRcdHRlWyA3IF0gPSBhMjEgKiBiMTMgKyBhMjIgKiBiMjMgKyBhMjMgKiBiMzM7XG5cblx0XHR0ZVsgMiBdID0gYTMxICogYjExICsgYTMyICogYjIxICsgYTMzICogYjMxO1xuXHRcdHRlWyA1IF0gPSBhMzEgKiBiMTIgKyBhMzIgKiBiMjIgKyBhMzMgKiBiMzI7XG5cdFx0dGVbIDggXSA9IGEzMSAqIGIxMyArIGEzMiAqIGIyMyArIGEzMyAqIGIzMztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0bXVsdGlwbHlTY2FsYXI6IGZ1bmN0aW9uICggcyApIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR0ZVsgMCBdICo9IHM7IHRlWyAzIF0gKj0gczsgdGVbIDYgXSAqPSBzO1xuXHRcdHRlWyAxIF0gKj0gczsgdGVbIDQgXSAqPSBzOyB0ZVsgNyBdICo9IHM7XG5cdFx0dGVbIDIgXSAqPSBzOyB0ZVsgNSBdICo9IHM7IHRlWyA4IF0gKj0gcztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGV0ZXJtaW5hbnQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB0ZSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR2YXIgYSA9IHRlWyAwIF0sIGIgPSB0ZVsgMSBdLCBjID0gdGVbIDIgXSxcblx0XHRcdGQgPSB0ZVsgMyBdLCBlID0gdGVbIDQgXSwgZiA9IHRlWyA1IF0sXG5cdFx0XHRnID0gdGVbIDYgXSwgaCA9IHRlWyA3IF0sIGkgPSB0ZVsgOCBdO1xuXG5cdFx0cmV0dXJuIGEgKiBlICogaSAtIGEgKiBmICogaCAtIGIgKiBkICogaSArIGIgKiBmICogZyArIGMgKiBkICogaCAtIGMgKiBlICogZztcblxuXHR9LFxuXG5cdGdldEludmVyc2U6IGZ1bmN0aW9uICggbWF0cml4LCB0aHJvd09uRGVnZW5lcmF0ZSApIHtcblxuXHRcdGlmICggbWF0cml4ICYmIG1hdHJpeC5pc01hdHJpeDQgKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoIFwiVEhSRUUuTWF0cml4My5nZXRJbnZlcnNlIG5vIGxvbmdlciB0YWtlcyBhIE1hdHJpeDQgYXJndW1lbnQuXCIgKTtcblxuXHRcdH1cblxuXHRcdHZhciBtZSA9IG1hdHJpeC5lbGVtZW50cyxcblx0XHRcdHRlID0gdGhpcy5lbGVtZW50cyxcblxuXHRcdFx0bjExID0gbWVbIDAgXSwgbjIxID0gbWVbIDEgXSwgbjMxID0gbWVbIDIgXSxcblx0XHRcdG4xMiA9IG1lWyAzIF0sIG4yMiA9IG1lWyA0IF0sIG4zMiA9IG1lWyA1IF0sXG5cdFx0XHRuMTMgPSBtZVsgNiBdLCBuMjMgPSBtZVsgNyBdLCBuMzMgPSBtZVsgOCBdLFxuXG5cdFx0XHR0MTEgPSBuMzMgKiBuMjIgLSBuMzIgKiBuMjMsXG5cdFx0XHR0MTIgPSBuMzIgKiBuMTMgLSBuMzMgKiBuMTIsXG5cdFx0XHR0MTMgPSBuMjMgKiBuMTIgLSBuMjIgKiBuMTMsXG5cblx0XHRcdGRldCA9IG4xMSAqIHQxMSArIG4yMSAqIHQxMiArIG4zMSAqIHQxMztcblxuXHRcdGlmICggZGV0ID09PSAwICkge1xuXG5cdFx0XHR2YXIgbXNnID0gXCJUSFJFRS5NYXRyaXgzLmdldEludmVyc2UoKTogY2FuJ3QgaW52ZXJ0IG1hdHJpeCwgZGV0ZXJtaW5hbnQgaXMgMFwiO1xuXG5cdFx0XHRpZiAoIHRocm93T25EZWdlbmVyYXRlID09PSB0cnVlICkge1xuXG5cdFx0XHRcdHRocm93IG5ldyBFcnJvciggbXNnICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCBtc2cgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdGhpcy5pZGVudGl0eSgpO1xuXG5cdFx0fVxuXG5cdFx0dmFyIGRldEludiA9IDEgLyBkZXQ7XG5cblx0XHR0ZVsgMCBdID0gdDExICogZGV0SW52O1xuXHRcdHRlWyAxIF0gPSAoIG4zMSAqIG4yMyAtIG4zMyAqIG4yMSApICogZGV0SW52O1xuXHRcdHRlWyAyIF0gPSAoIG4zMiAqIG4yMSAtIG4zMSAqIG4yMiApICogZGV0SW52O1xuXG5cdFx0dGVbIDMgXSA9IHQxMiAqIGRldEludjtcblx0XHR0ZVsgNCBdID0gKCBuMzMgKiBuMTEgLSBuMzEgKiBuMTMgKSAqIGRldEludjtcblx0XHR0ZVsgNSBdID0gKCBuMzEgKiBuMTIgLSBuMzIgKiBuMTEgKSAqIGRldEludjtcblxuXHRcdHRlWyA2IF0gPSB0MTMgKiBkZXRJbnY7XG5cdFx0dGVbIDcgXSA9ICggbjIxICogbjEzIC0gbjIzICogbjExICkgKiBkZXRJbnY7XG5cdFx0dGVbIDggXSA9ICggbjIyICogbjExIC0gbjIxICogbjEyICkgKiBkZXRJbnY7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRyYW5zcG9zZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHRtcCwgbSA9IHRoaXMuZWxlbWVudHM7XG5cblx0XHR0bXAgPSBtWyAxIF07IG1bIDEgXSA9IG1bIDMgXTsgbVsgMyBdID0gdG1wO1xuXHRcdHRtcCA9IG1bIDIgXTsgbVsgMiBdID0gbVsgNiBdOyBtWyA2IF0gPSB0bXA7XG5cdFx0dG1wID0gbVsgNSBdOyBtWyA1IF0gPSBtWyA3IF07IG1bIDcgXSA9IHRtcDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Z2V0Tm9ybWFsTWF0cml4OiBmdW5jdGlvbiAoIG1hdHJpeDQgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5zZXRGcm9tTWF0cml4NCggbWF0cml4NCApLmdldEludmVyc2UoIHRoaXMgKS50cmFuc3Bvc2UoKTtcblxuXHR9LFxuXG5cdHRyYW5zcG9zZUludG9BcnJheTogZnVuY3Rpb24gKCByICkge1xuXG5cdFx0dmFyIG0gPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0clsgMCBdID0gbVsgMCBdO1xuXHRcdHJbIDEgXSA9IG1bIDMgXTtcblx0XHRyWyAyIF0gPSBtWyA2IF07XG5cdFx0clsgMyBdID0gbVsgMSBdO1xuXHRcdHJbIDQgXSA9IG1bIDQgXTtcblx0XHRyWyA1IF0gPSBtWyA3IF07XG5cdFx0clsgNiBdID0gbVsgMiBdO1xuXHRcdHJbIDcgXSA9IG1bIDUgXTtcblx0XHRyWyA4IF0gPSBtWyA4IF07XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGVxdWFsczogZnVuY3Rpb24gKCBtYXRyaXggKSB7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdHZhciBtZSA9IG1hdHJpeC5lbGVtZW50cztcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IDk7IGkgKysgKSB7XG5cblx0XHRcdGlmICggdGVbIGkgXSAhPT0gbWVbIGkgXSApIHJldHVybiBmYWxzZTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXG5cdH0sXG5cblx0ZnJvbUFycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IDk7IGkgKysgKSB7XG5cblx0XHRcdHRoaXMuZWxlbWVudHNbIGkgXSA9IGFycmF5WyBpICsgb2Zmc2V0IF07XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uICggYXJyYXksIG9mZnNldCApIHtcblxuXHRcdGlmICggYXJyYXkgPT09IHVuZGVmaW5lZCApIGFycmF5ID0gW107XG5cdFx0aWYgKCBvZmZzZXQgPT09IHVuZGVmaW5lZCApIG9mZnNldCA9IDA7XG5cblx0XHR2YXIgdGUgPSB0aGlzLmVsZW1lbnRzO1xuXG5cdFx0YXJyYXlbIG9mZnNldCBdID0gdGVbIDAgXTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMSBdID0gdGVbIDEgXTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMiBdID0gdGVbIDIgXTtcblxuXHRcdGFycmF5WyBvZmZzZXQgKyAzIF0gPSB0ZVsgMyBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyA0IF0gPSB0ZVsgNCBdO1xuXHRcdGFycmF5WyBvZmZzZXQgKyA1IF0gPSB0ZVsgNSBdO1xuXG5cdFx0YXJyYXlbIG9mZnNldCArIDYgXSA9IHRlWyA2IF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDcgXSA9IHRlWyA3IF07XG5cdFx0YXJyYXlbIG9mZnNldCArIDggXSA9IHRlWyA4IF07XG5cblx0XHRyZXR1cm4gYXJyYXk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICovXG5cbmZ1bmN0aW9uIFBsYW5lKCBub3JtYWwsIGNvbnN0YW50ICkge1xuXG5cdHRoaXMubm9ybWFsID0gKCBub3JtYWwgIT09IHVuZGVmaW5lZCApID8gbm9ybWFsIDogbmV3IFZlY3RvcjMoIDEsIDAsIDAgKTtcblx0dGhpcy5jb25zdGFudCA9ICggY29uc3RhbnQgIT09IHVuZGVmaW5lZCApID8gY29uc3RhbnQgOiAwO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFBsYW5lLnByb3RvdHlwZSwge1xuXG5cdHNldDogZnVuY3Rpb24gKCBub3JtYWwsIGNvbnN0YW50ICkge1xuXG5cdFx0dGhpcy5ub3JtYWwuY29weSggbm9ybWFsICk7XG5cdFx0dGhpcy5jb25zdGFudCA9IGNvbnN0YW50O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRDb21wb25lbnRzOiBmdW5jdGlvbiAoIHgsIHksIHosIHcgKSB7XG5cblx0XHR0aGlzLm5vcm1hbC5zZXQoIHgsIHksIHogKTtcblx0XHR0aGlzLmNvbnN0YW50ID0gdztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbU5vcm1hbEFuZENvcGxhbmFyUG9pbnQ6IGZ1bmN0aW9uICggbm9ybWFsLCBwb2ludCApIHtcblxuXHRcdHRoaXMubm9ybWFsLmNvcHkoIG5vcm1hbCApO1xuXHRcdHRoaXMuY29uc3RhbnQgPSAtIHBvaW50LmRvdCggdGhpcy5ub3JtYWwgKTtcdC8vIG11c3QgYmUgdGhpcy5ub3JtYWwsIG5vdCBub3JtYWwsIGFzIHRoaXMubm9ybWFsIGlzIG5vcm1hbGl6ZWRcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbUNvcGxhbmFyUG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB2MiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gc2V0RnJvbUNvcGxhbmFyUG9pbnRzKCBhLCBiLCBjICkge1xuXG5cdFx0XHR2YXIgbm9ybWFsID0gdjEuc3ViVmVjdG9ycyggYywgYiApLmNyb3NzKCB2Mi5zdWJWZWN0b3JzKCBhLCBiICkgKS5ub3JtYWxpemUoKTtcblxuXHRcdFx0Ly8gUTogc2hvdWxkIGFuIGVycm9yIGJlIHRocm93biBpZiBub3JtYWwgaXMgemVybyAoZS5nLiBkZWdlbmVyYXRlIHBsYW5lKT9cblxuXHRcdFx0dGhpcy5zZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludCggbm9ybWFsLCBhICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggcGxhbmUgKSB7XG5cblx0XHR0aGlzLm5vcm1hbC5jb3B5KCBwbGFuZS5ub3JtYWwgKTtcblx0XHR0aGlzLmNvbnN0YW50ID0gcGxhbmUuY29uc3RhbnQ7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG5vcm1hbGl6ZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gTm90ZTogd2lsbCBsZWFkIHRvIGEgZGl2aWRlIGJ5IHplcm8gaWYgdGhlIHBsYW5lIGlzIGludmFsaWQuXG5cblx0XHR2YXIgaW52ZXJzZU5vcm1hbExlbmd0aCA9IDEuMCAvIHRoaXMubm9ybWFsLmxlbmd0aCgpO1xuXHRcdHRoaXMubm9ybWFsLm11bHRpcGx5U2NhbGFyKCBpbnZlcnNlTm9ybWFsTGVuZ3RoICk7XG5cdFx0dGhpcy5jb25zdGFudCAqPSBpbnZlcnNlTm9ybWFsTGVuZ3RoO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRuZWdhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuY29uc3RhbnQgKj0gLSAxO1xuXHRcdHRoaXMubm9ybWFsLm5lZ2F0ZSgpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRkaXN0YW5jZVRvUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5ub3JtYWwuZG90KCBwb2ludCApICsgdGhpcy5jb25zdGFudDtcblxuXHR9LFxuXG5cdGRpc3RhbmNlVG9TcGhlcmU6IGZ1bmN0aW9uICggc3BoZXJlICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZGlzdGFuY2VUb1BvaW50KCBzcGhlcmUuY2VudGVyICkgLSBzcGhlcmUucmFkaXVzO1xuXG5cdH0sXG5cblx0cHJvamVjdFBvaW50OiBmdW5jdGlvbiAoIHBvaW50LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHJldHVybiB0aGlzLm9ydGhvUG9pbnQoIHBvaW50LCBvcHRpb25hbFRhcmdldCApLnN1YiggcG9pbnQgKS5uZWdhdGUoKTtcblxuXHR9LFxuXG5cdG9ydGhvUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHBlcnBlbmRpY3VsYXJNYWduaXR1ZGUgPSB0aGlzLmRpc3RhbmNlVG9Qb2ludCggcG9pbnQgKTtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdHJldHVybiByZXN1bHQuY29weSggdGhpcy5ub3JtYWwgKS5tdWx0aXBseVNjYWxhciggcGVycGVuZGljdWxhck1hZ25pdHVkZSApO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0TGluZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBpbnRlcnNlY3RMaW5lKCBsaW5lLCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRcdHZhciBkaXJlY3Rpb24gPSBsaW5lLmRlbHRhKCB2MSApO1xuXG5cdFx0XHR2YXIgZGVub21pbmF0b3IgPSB0aGlzLm5vcm1hbC5kb3QoIGRpcmVjdGlvbiApO1xuXG5cdFx0XHRpZiAoIGRlbm9taW5hdG9yID09PSAwICkge1xuXG5cdFx0XHRcdC8vIGxpbmUgaXMgY29wbGFuYXIsIHJldHVybiBvcmlnaW5cblx0XHRcdFx0aWYgKCB0aGlzLmRpc3RhbmNlVG9Qb2ludCggbGluZS5zdGFydCApID09PSAwICkge1xuXG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdC5jb3B5KCBsaW5lLnN0YXJ0ICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFVuc3VyZSBpZiB0aGlzIGlzIHRoZSBjb3JyZWN0IG1ldGhvZCB0byBoYW5kbGUgdGhpcyBjYXNlLlxuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciB0ID0gLSAoIGxpbmUuc3RhcnQuZG90KCB0aGlzLm5vcm1hbCApICsgdGhpcy5jb25zdGFudCApIC8gZGVub21pbmF0b3I7XG5cblx0XHRcdGlmICggdCA8IDAgfHwgdCA+IDEgKSB7XG5cblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0LmNvcHkoIGRpcmVjdGlvbiApLm11bHRpcGx5U2NhbGFyKCB0ICkuYWRkKCBsaW5lLnN0YXJ0ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRpbnRlcnNlY3RzTGluZTogZnVuY3Rpb24gKCBsaW5lICkge1xuXG5cdFx0Ly8gTm90ZTogdGhpcyB0ZXN0cyBpZiBhIGxpbmUgaW50ZXJzZWN0cyB0aGUgcGxhbmUsIG5vdCB3aGV0aGVyIGl0IChvciBpdHMgZW5kLXBvaW50cykgYXJlIGNvcGxhbmFyIHdpdGggaXQuXG5cblx0XHR2YXIgc3RhcnRTaWduID0gdGhpcy5kaXN0YW5jZVRvUG9pbnQoIGxpbmUuc3RhcnQgKTtcblx0XHR2YXIgZW5kU2lnbiA9IHRoaXMuZGlzdGFuY2VUb1BvaW50KCBsaW5lLmVuZCApO1xuXG5cdFx0cmV0dXJuICggc3RhcnRTaWduIDwgMCAmJiBlbmRTaWduID4gMCApIHx8ICggZW5kU2lnbiA8IDAgJiYgc3RhcnRTaWduID4gMCApO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0c0JveDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHRyZXR1cm4gYm94LmludGVyc2VjdHNQbGFuZSggdGhpcyApO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0c1NwaGVyZTogZnVuY3Rpb24gKCBzcGhlcmUgKSB7XG5cblx0XHRyZXR1cm4gc3BoZXJlLmludGVyc2VjdHNQbGFuZSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29wbGFuYXJQb2ludDogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdHJldHVybiByZXN1bHQuY29weSggdGhpcy5ub3JtYWwgKS5tdWx0aXBseVNjYWxhciggLSB0aGlzLmNvbnN0YW50ICk7XG5cblx0fSxcblxuXHRhcHBseU1hdHJpeDQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIG0xID0gbmV3IE1hdHJpeDMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBhcHBseU1hdHJpeDQoIG1hdHJpeCwgb3B0aW9uYWxOb3JtYWxNYXRyaXggKSB7XG5cblx0XHRcdHZhciByZWZlcmVuY2VQb2ludCA9IHRoaXMuY29wbGFuYXJQb2ludCggdjEgKS5hcHBseU1hdHJpeDQoIG1hdHJpeCApO1xuXG5cdFx0XHQvLyB0cmFuc2Zvcm0gbm9ybWFsIGJhc2VkIG9uIHRoZW9yeSBoZXJlOlxuXHRcdFx0Ly8gaHR0cDovL3d3dy5zb25naG8uY2Evb3BlbmdsL2dsX25vcm1hbHRyYW5zZm9ybS5odG1sXG5cdFx0XHR2YXIgbm9ybWFsTWF0cml4ID0gb3B0aW9uYWxOb3JtYWxNYXRyaXggfHwgbTEuZ2V0Tm9ybWFsTWF0cml4KCBtYXRyaXggKTtcblx0XHRcdHZhciBub3JtYWwgPSB0aGlzLm5vcm1hbC5hcHBseU1hdHJpeDMoIG5vcm1hbE1hdHJpeCApLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHQvLyByZWNhbGN1bGF0ZSBjb25zdGFudCAobGlrZSBpbiBzZXRGcm9tTm9ybWFsQW5kQ29wbGFuYXJQb2ludClcblx0XHRcdHRoaXMuY29uc3RhbnQgPSAtIHJlZmVyZW5jZVBvaW50LmRvdCggbm9ybWFsICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoIG9mZnNldCApIHtcblxuXHRcdHRoaXMuY29uc3RhbnQgPSB0aGlzLmNvbnN0YW50IC0gb2Zmc2V0LmRvdCggdGhpcy5ub3JtYWwgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIHBsYW5lICkge1xuXG5cdFx0cmV0dXJuIHBsYW5lLm5vcm1hbC5lcXVhbHMoIHRoaXMubm9ybWFsICkgJiYgKCBwbGFuZS5jb25zdGFudCA9PT0gdGhpcy5jb25zdGFudCApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICovXG5cbmZ1bmN0aW9uIEZydXN0dW0oIHAwLCBwMSwgcDIsIHAzLCBwNCwgcDUgKSB7XG5cblx0dGhpcy5wbGFuZXMgPSBbXG5cblx0XHQoIHAwICE9PSB1bmRlZmluZWQgKSA/IHAwIDogbmV3IFBsYW5lKCksXG5cdFx0KCBwMSAhPT0gdW5kZWZpbmVkICkgPyBwMSA6IG5ldyBQbGFuZSgpLFxuXHRcdCggcDIgIT09IHVuZGVmaW5lZCApID8gcDIgOiBuZXcgUGxhbmUoKSxcblx0XHQoIHAzICE9PSB1bmRlZmluZWQgKSA/IHAzIDogbmV3IFBsYW5lKCksXG5cdFx0KCBwNCAhPT0gdW5kZWZpbmVkICkgPyBwNCA6IG5ldyBQbGFuZSgpLFxuXHRcdCggcDUgIT09IHVuZGVmaW5lZCApID8gcDUgOiBuZXcgUGxhbmUoKVxuXG5cdF07XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggRnJ1c3R1bS5wcm90b3R5cGUsIHtcblxuXHRzZXQ6IGZ1bmN0aW9uICggcDAsIHAxLCBwMiwgcDMsIHA0LCBwNSApIHtcblxuXHRcdHZhciBwbGFuZXMgPSB0aGlzLnBsYW5lcztcblxuXHRcdHBsYW5lc1sgMCBdLmNvcHkoIHAwICk7XG5cdFx0cGxhbmVzWyAxIF0uY29weSggcDEgKTtcblx0XHRwbGFuZXNbIDIgXS5jb3B5KCBwMiApO1xuXHRcdHBsYW5lc1sgMyBdLmNvcHkoIHAzICk7XG5cdFx0cGxhbmVzWyA0IF0uY29weSggcDQgKTtcblx0XHRwbGFuZXNbIDUgXS5jb3B5KCBwNSApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBmcnVzdHVtICkge1xuXG5cdFx0dmFyIHBsYW5lcyA9IHRoaXMucGxhbmVzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0cGxhbmVzWyBpIF0uY29weSggZnJ1c3R1bS5wbGFuZXNbIGkgXSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tTWF0cml4OiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHR2YXIgcGxhbmVzID0gdGhpcy5wbGFuZXM7XG5cdFx0dmFyIG1lID0gbS5lbGVtZW50cztcblx0XHR2YXIgbWUwID0gbWVbIDAgXSwgbWUxID0gbWVbIDEgXSwgbWUyID0gbWVbIDIgXSwgbWUzID0gbWVbIDMgXTtcblx0XHR2YXIgbWU0ID0gbWVbIDQgXSwgbWU1ID0gbWVbIDUgXSwgbWU2ID0gbWVbIDYgXSwgbWU3ID0gbWVbIDcgXTtcblx0XHR2YXIgbWU4ID0gbWVbIDggXSwgbWU5ID0gbWVbIDkgXSwgbWUxMCA9IG1lWyAxMCBdLCBtZTExID0gbWVbIDExIF07XG5cdFx0dmFyIG1lMTIgPSBtZVsgMTIgXSwgbWUxMyA9IG1lWyAxMyBdLCBtZTE0ID0gbWVbIDE0IF0sIG1lMTUgPSBtZVsgMTUgXTtcblxuXHRcdHBsYW5lc1sgMCBdLnNldENvbXBvbmVudHMoIG1lMyAtIG1lMCwgbWU3IC0gbWU0LCBtZTExIC0gbWU4LCBtZTE1IC0gbWUxMiApLm5vcm1hbGl6ZSgpO1xuXHRcdHBsYW5lc1sgMSBdLnNldENvbXBvbmVudHMoIG1lMyArIG1lMCwgbWU3ICsgbWU0LCBtZTExICsgbWU4LCBtZTE1ICsgbWUxMiApLm5vcm1hbGl6ZSgpO1xuXHRcdHBsYW5lc1sgMiBdLnNldENvbXBvbmVudHMoIG1lMyArIG1lMSwgbWU3ICsgbWU1LCBtZTExICsgbWU5LCBtZTE1ICsgbWUxMyApLm5vcm1hbGl6ZSgpO1xuXHRcdHBsYW5lc1sgMyBdLnNldENvbXBvbmVudHMoIG1lMyAtIG1lMSwgbWU3IC0gbWU1LCBtZTExIC0gbWU5LCBtZTE1IC0gbWUxMyApLm5vcm1hbGl6ZSgpO1xuXHRcdHBsYW5lc1sgNCBdLnNldENvbXBvbmVudHMoIG1lMyAtIG1lMiwgbWU3IC0gbWU2LCBtZTExIC0gbWUxMCwgbWUxNSAtIG1lMTQgKS5ub3JtYWxpemUoKTtcblx0XHRwbGFuZXNbIDUgXS5zZXRDb21wb25lbnRzKCBtZTMgKyBtZTIsIG1lNyArIG1lNiwgbWUxMSArIG1lMTAsIG1lMTUgKyBtZTE0ICkubm9ybWFsaXplKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGludGVyc2VjdHNPYmplY3Q6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBzcGhlcmUgPSBuZXcgU3BoZXJlKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gaW50ZXJzZWN0c09iamVjdCggb2JqZWN0ICkge1xuXG5cdFx0XHR2YXIgZ2VvbWV0cnkgPSBvYmplY3QuZ2VvbWV0cnk7XG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUgPT09IG51bGwgKVxuXHRcdFx0XHRnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTtcblxuXHRcdFx0c3BoZXJlLmNvcHkoIGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlIClcblx0XHRcdFx0LmFwcGx5TWF0cml4NCggb2JqZWN0Lm1hdHJpeFdvcmxkICk7XG5cblx0XHRcdHJldHVybiB0aGlzLmludGVyc2VjdHNTcGhlcmUoIHNwaGVyZSApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0aW50ZXJzZWN0c1Nwcml0ZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHNwaGVyZSA9IG5ldyBTcGhlcmUoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBpbnRlcnNlY3RzU3ByaXRlKCBzcHJpdGUgKSB7XG5cblx0XHRcdHNwaGVyZS5jZW50ZXIuc2V0KCAwLCAwLCAwICk7XG5cdFx0XHRzcGhlcmUucmFkaXVzID0gMC43MDcxMDY3ODExODY1NDc2O1xuXHRcdFx0c3BoZXJlLmFwcGx5TWF0cml4NCggc3ByaXRlLm1hdHJpeFdvcmxkICk7XG5cblx0XHRcdHJldHVybiB0aGlzLmludGVyc2VjdHNTcGhlcmUoIHNwaGVyZSApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0aW50ZXJzZWN0c1NwaGVyZTogZnVuY3Rpb24gKCBzcGhlcmUgKSB7XG5cblx0XHR2YXIgcGxhbmVzID0gdGhpcy5wbGFuZXM7XG5cdFx0dmFyIGNlbnRlciA9IHNwaGVyZS5jZW50ZXI7XG5cdFx0dmFyIG5lZ1JhZGl1cyA9IC0gc3BoZXJlLnJhZGl1cztcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IDY7IGkgKysgKSB7XG5cblx0XHRcdHZhciBkaXN0YW5jZSA9IHBsYW5lc1sgaSBdLmRpc3RhbmNlVG9Qb2ludCggY2VudGVyICk7XG5cblx0XHRcdGlmICggZGlzdGFuY2UgPCBuZWdSYWRpdXMgKSB7XG5cblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblxuXHR9LFxuXG5cdGludGVyc2VjdHNCb3g6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBwMSA9IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRwMiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gaW50ZXJzZWN0c0JveCggYm94ICkge1xuXG5cdFx0XHR2YXIgcGxhbmVzID0gdGhpcy5wbGFuZXM7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IDY7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIHBsYW5lID0gcGxhbmVzWyBpIF07XG5cblx0XHRcdFx0cDEueCA9IHBsYW5lLm5vcm1hbC54ID4gMCA/IGJveC5taW4ueCA6IGJveC5tYXgueDtcblx0XHRcdFx0cDIueCA9IHBsYW5lLm5vcm1hbC54ID4gMCA/IGJveC5tYXgueCA6IGJveC5taW4ueDtcblx0XHRcdFx0cDEueSA9IHBsYW5lLm5vcm1hbC55ID4gMCA/IGJveC5taW4ueSA6IGJveC5tYXgueTtcblx0XHRcdFx0cDIueSA9IHBsYW5lLm5vcm1hbC55ID4gMCA/IGJveC5tYXgueSA6IGJveC5taW4ueTtcblx0XHRcdFx0cDEueiA9IHBsYW5lLm5vcm1hbC56ID4gMCA/IGJveC5taW4ueiA6IGJveC5tYXguejtcblx0XHRcdFx0cDIueiA9IHBsYW5lLm5vcm1hbC56ID4gMCA/IGJveC5tYXgueiA6IGJveC5taW4uejtcblxuXHRcdFx0XHR2YXIgZDEgPSBwbGFuZS5kaXN0YW5jZVRvUG9pbnQoIHAxICk7XG5cdFx0XHRcdHZhciBkMiA9IHBsYW5lLmRpc3RhbmNlVG9Qb2ludCggcDIgKTtcblxuXHRcdFx0XHQvLyBpZiBib3RoIG91dHNpZGUgcGxhbmUsIG5vIGludGVyc2VjdGlvblxuXG5cdFx0XHRcdGlmICggZDEgPCAwICYmIGQyIDwgMCApIHtcblxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRjb250YWluc1BvaW50OiBmdW5jdGlvbiAoIHBvaW50ICkge1xuXG5cdFx0dmFyIHBsYW5lcyA9IHRoaXMucGxhbmVzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0aWYgKCBwbGFuZXNbIGkgXS5kaXN0YW5jZVRvUG9pbnQoIHBvaW50ICkgPCAwICkge1xuXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gV2ViR0xTaGFkb3dNYXAoIF9yZW5kZXJlciwgX2xpZ2h0cywgX29iamVjdHMsIGNhcGFiaWxpdGllcyApIHtcblxuXHR2YXIgX2dsID0gX3JlbmRlcmVyLmNvbnRleHQsXG5cdFx0X3N0YXRlID0gX3JlbmRlcmVyLnN0YXRlLFxuXHRcdF9mcnVzdHVtID0gbmV3IEZydXN0dW0oKSxcblx0XHRfcHJvalNjcmVlbk1hdHJpeCA9IG5ldyBNYXRyaXg0KCksXG5cblx0XHRfbGlnaHRTaGFkb3dzID0gX2xpZ2h0cy5zaGFkb3dzLFxuXG5cdFx0X3NoYWRvd01hcFNpemUgPSBuZXcgVmVjdG9yMigpLFxuXHRcdF9tYXhTaGFkb3dNYXBTaXplID0gbmV3IFZlY3RvcjIoIGNhcGFiaWxpdGllcy5tYXhUZXh0dXJlU2l6ZSwgY2FwYWJpbGl0aWVzLm1heFRleHR1cmVTaXplICksXG5cblx0XHRfbG9va1RhcmdldCA9IG5ldyBWZWN0b3IzKCksXG5cdFx0X2xpZ2h0UG9zaXRpb25Xb3JsZCA9IG5ldyBWZWN0b3IzKCksXG5cblx0XHRfTW9ycGhpbmdGbGFnID0gMSxcblx0XHRfU2tpbm5pbmdGbGFnID0gMixcblxuXHRcdF9OdW1iZXJPZk1hdGVyaWFsVmFyaWFudHMgPSAoIF9Nb3JwaGluZ0ZsYWcgfCBfU2tpbm5pbmdGbGFnICkgKyAxLFxuXG5cdFx0X2RlcHRoTWF0ZXJpYWxzID0gbmV3IEFycmF5KCBfTnVtYmVyT2ZNYXRlcmlhbFZhcmlhbnRzICksXG5cdFx0X2Rpc3RhbmNlTWF0ZXJpYWxzID0gbmV3IEFycmF5KCBfTnVtYmVyT2ZNYXRlcmlhbFZhcmlhbnRzICksXG5cblx0XHRfbWF0ZXJpYWxDYWNoZSA9IHt9O1xuXG5cdHZhciBjdWJlRGlyZWN0aW9ucyA9IFtcblx0XHRuZXcgVmVjdG9yMyggMSwgMCwgMCApLCBuZXcgVmVjdG9yMyggLSAxLCAwLCAwICksIG5ldyBWZWN0b3IzKCAwLCAwLCAxICksXG5cdFx0bmV3IFZlY3RvcjMoIDAsIDAsIC0gMSApLCBuZXcgVmVjdG9yMyggMCwgMSwgMCApLCBuZXcgVmVjdG9yMyggMCwgLSAxLCAwIClcblx0XTtcblxuXHR2YXIgY3ViZVVwcyA9IFtcblx0XHRuZXcgVmVjdG9yMyggMCwgMSwgMCApLCBuZXcgVmVjdG9yMyggMCwgMSwgMCApLCBuZXcgVmVjdG9yMyggMCwgMSwgMCApLFxuXHRcdG5ldyBWZWN0b3IzKCAwLCAxLCAwICksIG5ldyBWZWN0b3IzKCAwLCAwLCAxICksXHRuZXcgVmVjdG9yMyggMCwgMCwgLSAxIClcblx0XTtcblxuXHR2YXIgY3ViZTJEVmlld1BvcnRzID0gW1xuXHRcdG5ldyBWZWN0b3I0KCksIG5ldyBWZWN0b3I0KCksIG5ldyBWZWN0b3I0KCksXG5cdFx0bmV3IFZlY3RvcjQoKSwgbmV3IFZlY3RvcjQoKSwgbmV3IFZlY3RvcjQoKVxuXHRdO1xuXG5cdC8vIGluaXRcblxuXHR2YXIgZGVwdGhNYXRlcmlhbFRlbXBsYXRlID0gbmV3IE1lc2hEZXB0aE1hdGVyaWFsKCk7XG5cdGRlcHRoTWF0ZXJpYWxUZW1wbGF0ZS5kZXB0aFBhY2tpbmcgPSBSR0JBRGVwdGhQYWNraW5nO1xuXHRkZXB0aE1hdGVyaWFsVGVtcGxhdGUuY2xpcHBpbmcgPSB0cnVlO1xuXG5cdHZhciBkaXN0YW5jZVNoYWRlciA9IFNoYWRlckxpYlsgXCJkaXN0YW5jZVJHQkFcIiBdO1xuXHR2YXIgZGlzdGFuY2VVbmlmb3JtcyA9IFVuaWZvcm1zVXRpbHMuY2xvbmUoIGRpc3RhbmNlU2hhZGVyLnVuaWZvcm1zICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBfTnVtYmVyT2ZNYXRlcmlhbFZhcmlhbnRzOyArKyBpICkge1xuXG5cdFx0dmFyIHVzZU1vcnBoaW5nID0gKCBpICYgX01vcnBoaW5nRmxhZyApICE9PSAwO1xuXHRcdHZhciB1c2VTa2lubmluZyA9ICggaSAmIF9Ta2lubmluZ0ZsYWcgKSAhPT0gMDtcblxuXHRcdHZhciBkZXB0aE1hdGVyaWFsID0gZGVwdGhNYXRlcmlhbFRlbXBsYXRlLmNsb25lKCk7XG5cdFx0ZGVwdGhNYXRlcmlhbC5tb3JwaFRhcmdldHMgPSB1c2VNb3JwaGluZztcblx0XHRkZXB0aE1hdGVyaWFsLnNraW5uaW5nID0gdXNlU2tpbm5pbmc7XG5cblx0XHRfZGVwdGhNYXRlcmlhbHNbIGkgXSA9IGRlcHRoTWF0ZXJpYWw7XG5cblx0XHR2YXIgZGlzdGFuY2VNYXRlcmlhbCA9IG5ldyBTaGFkZXJNYXRlcmlhbCgge1xuXHRcdFx0ZGVmaW5lczoge1xuXHRcdFx0XHQnVVNFX1NIQURPV01BUCc6ICcnXG5cdFx0XHR9LFxuXHRcdFx0dW5pZm9ybXM6IGRpc3RhbmNlVW5pZm9ybXMsXG5cdFx0XHR2ZXJ0ZXhTaGFkZXI6IGRpc3RhbmNlU2hhZGVyLnZlcnRleFNoYWRlcixcblx0XHRcdGZyYWdtZW50U2hhZGVyOiBkaXN0YW5jZVNoYWRlci5mcmFnbWVudFNoYWRlcixcblx0XHRcdG1vcnBoVGFyZ2V0czogdXNlTW9ycGhpbmcsXG5cdFx0XHRza2lubmluZzogdXNlU2tpbm5pbmcsXG5cdFx0XHRjbGlwcGluZzogdHJ1ZVxuXHRcdH0gKTtcblxuXHRcdF9kaXN0YW5jZU1hdGVyaWFsc1sgaSBdID0gZGlzdGFuY2VNYXRlcmlhbDtcblxuXHR9XG5cblx0Ly9cblxuXHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdHRoaXMuZW5hYmxlZCA9IGZhbHNlO1xuXG5cdHRoaXMuYXV0b1VwZGF0ZSA9IHRydWU7XG5cdHRoaXMubmVlZHNVcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLnR5cGUgPSBQQ0ZTaGFkb3dNYXA7XG5cblx0dGhpcy5yZW5kZXJSZXZlcnNlU2lkZWQgPSB0cnVlO1xuXHR0aGlzLnJlbmRlclNpbmdsZVNpZGVkID0gdHJ1ZTtcblxuXHR0aGlzLnJlbmRlciA9IGZ1bmN0aW9uICggc2NlbmUsIGNhbWVyYSApIHtcblxuXHRcdGlmICggc2NvcGUuZW5hYmxlZCA9PT0gZmFsc2UgKSByZXR1cm47XG5cdFx0aWYgKCBzY29wZS5hdXRvVXBkYXRlID09PSBmYWxzZSAmJiBzY29wZS5uZWVkc1VwZGF0ZSA9PT0gZmFsc2UgKSByZXR1cm47XG5cblx0XHRpZiAoIF9saWdodFNoYWRvd3MubGVuZ3RoID09PSAwICkgcmV0dXJuO1xuXG5cdFx0Ly8gU2V0IEdMIHN0YXRlIGZvciBkZXB0aCBtYXAuXG5cdFx0X3N0YXRlLmRpc2FibGUoIF9nbC5CTEVORCApO1xuXHRcdF9zdGF0ZS5idWZmZXJzLmNvbG9yLnNldENsZWFyKCAxLCAxLCAxLCAxICk7XG5cdFx0X3N0YXRlLmJ1ZmZlcnMuZGVwdGguc2V0VGVzdCggdHJ1ZSApO1xuXHRcdF9zdGF0ZS5zZXRTY2lzc29yVGVzdCggZmFsc2UgKTtcblxuXHRcdC8vIHJlbmRlciBkZXB0aCBtYXBcblxuXHRcdHZhciBmYWNlQ291bnQsIGlzUG9pbnRMaWdodDtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSBfbGlnaHRTaGFkb3dzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgbGlnaHQgPSBfbGlnaHRTaGFkb3dzWyBpIF07XG5cdFx0XHR2YXIgc2hhZG93ID0gbGlnaHQuc2hhZG93O1xuXG5cdFx0XHRpZiAoIHNoYWRvdyA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMU2hhZG93TWFwOicsIGxpZ2h0LCAnaGFzIG5vIHNoYWRvdy4nICk7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBzaGFkb3dDYW1lcmEgPSBzaGFkb3cuY2FtZXJhO1xuXHRcdFx0dmFyIHNoYWRvd01hdHJpeCA9IHNoYWRvdy5tYXRyaXg7XG5cblx0XHRcdF9saWdodFBvc2l0aW9uV29ybGQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBsaWdodC5tYXRyaXhXb3JsZCApO1xuXHRcdFx0c2hhZG93Q2FtZXJhLnBvc2l0aW9uLmNvcHkoIF9saWdodFBvc2l0aW9uV29ybGQgKTtcblxuXHRcdFx0X3NoYWRvd01hcFNpemUuY29weSggc2hhZG93Lm1hcFNpemUgKTtcblx0XHRcdF9zaGFkb3dNYXBTaXplLm1pbiggX21heFNoYWRvd01hcFNpemUgKTtcblxuXHRcdFx0aWYgKCBsaWdodCAmJiBsaWdodC5pc1BvaW50TGlnaHQgKSB7XG5cblx0XHRcdFx0ZmFjZUNvdW50ID0gNjtcblx0XHRcdFx0aXNQb2ludExpZ2h0ID0gdHJ1ZTtcblxuXHRcdFx0XHR2YXIgdnBXaWR0aCA9IF9zaGFkb3dNYXBTaXplLng7XG5cdFx0XHRcdHZhciB2cEhlaWdodCA9IF9zaGFkb3dNYXBTaXplLnk7XG5cblx0XHRcdFx0Ly8gVGhlc2Ugdmlld3BvcnRzIG1hcCBhIGN1YmUtbWFwIG9udG8gYSAyRCB0ZXh0dXJlIHdpdGggdGhlXG5cdFx0XHRcdC8vIGZvbGxvd2luZyBvcmllbnRhdGlvbjpcblx0XHRcdFx0Ly9cblx0XHRcdFx0Ly8gIHh6WFpcblx0XHRcdFx0Ly8gICB5IFlcblx0XHRcdFx0Ly9cblx0XHRcdFx0Ly8gWCAtIFBvc2l0aXZlIHggZGlyZWN0aW9uXG5cdFx0XHRcdC8vIHggLSBOZWdhdGl2ZSB4IGRpcmVjdGlvblxuXHRcdFx0XHQvLyBZIC0gUG9zaXRpdmUgeSBkaXJlY3Rpb25cblx0XHRcdFx0Ly8geSAtIE5lZ2F0aXZlIHkgZGlyZWN0aW9uXG5cdFx0XHRcdC8vIFogLSBQb3NpdGl2ZSB6IGRpcmVjdGlvblxuXHRcdFx0XHQvLyB6IC0gTmVnYXRpdmUgeiBkaXJlY3Rpb25cblxuXHRcdFx0XHQvLyBwb3NpdGl2ZSBYXG5cdFx0XHRcdGN1YmUyRFZpZXdQb3J0c1sgMCBdLnNldCggdnBXaWR0aCAqIDIsIHZwSGVpZ2h0LCB2cFdpZHRoLCB2cEhlaWdodCApO1xuXHRcdFx0XHQvLyBuZWdhdGl2ZSBYXG5cdFx0XHRcdGN1YmUyRFZpZXdQb3J0c1sgMSBdLnNldCggMCwgdnBIZWlnaHQsIHZwV2lkdGgsIHZwSGVpZ2h0ICk7XG5cdFx0XHRcdC8vIHBvc2l0aXZlIFpcblx0XHRcdFx0Y3ViZTJEVmlld1BvcnRzWyAyIF0uc2V0KCB2cFdpZHRoICogMywgdnBIZWlnaHQsIHZwV2lkdGgsIHZwSGVpZ2h0ICk7XG5cdFx0XHRcdC8vIG5lZ2F0aXZlIFpcblx0XHRcdFx0Y3ViZTJEVmlld1BvcnRzWyAzIF0uc2V0KCB2cFdpZHRoLCB2cEhlaWdodCwgdnBXaWR0aCwgdnBIZWlnaHQgKTtcblx0XHRcdFx0Ly8gcG9zaXRpdmUgWVxuXHRcdFx0XHRjdWJlMkRWaWV3UG9ydHNbIDQgXS5zZXQoIHZwV2lkdGggKiAzLCAwLCB2cFdpZHRoLCB2cEhlaWdodCApO1xuXHRcdFx0XHQvLyBuZWdhdGl2ZSBZXG5cdFx0XHRcdGN1YmUyRFZpZXdQb3J0c1sgNSBdLnNldCggdnBXaWR0aCwgMCwgdnBXaWR0aCwgdnBIZWlnaHQgKTtcblxuXHRcdFx0XHRfc2hhZG93TWFwU2l6ZS54ICo9IDQuMDtcblx0XHRcdFx0X3NoYWRvd01hcFNpemUueSAqPSAyLjA7XG5cblxuXHRcdFx0XHQvLyBmb3IgcG9pbnQgbGlnaHRzIHdlIHNldCB0aGUgc2hhZG93IG1hdHJpeCB0byBiZSBhIHRyYW5zbGF0aW9uLW9ubHkgbWF0cml4XG5cdFx0XHRcdC8vIGVxdWFsIHRvIGludmVyc2Ugb2YgdGhlIGxpZ2h0J3MgcG9zaXRpb25cblxuXHRcdFx0XHRzaGFkb3dNYXRyaXgubWFrZVRyYW5zbGF0aW9uKCAtIF9saWdodFBvc2l0aW9uV29ybGQueCwgLSBfbGlnaHRQb3NpdGlvbldvcmxkLnksIC0gX2xpZ2h0UG9zaXRpb25Xb3JsZC56ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0ZmFjZUNvdW50ID0gMTtcblx0XHRcdFx0aXNQb2ludExpZ2h0ID0gZmFsc2U7XG5cblx0XHRcdFx0X2xvb2tUYXJnZXQuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBsaWdodC50YXJnZXQubWF0cml4V29ybGQgKTtcblx0XHRcdFx0c2hhZG93Q2FtZXJhLmxvb2tBdCggX2xvb2tUYXJnZXQgKTtcblx0XHRcdFx0c2hhZG93Q2FtZXJhLnVwZGF0ZU1hdHJpeFdvcmxkKCk7XG5cdFx0XHRcdHNoYWRvd0NhbWVyYS5tYXRyaXhXb3JsZEludmVyc2UuZ2V0SW52ZXJzZSggc2hhZG93Q2FtZXJhLm1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0Ly8gY29tcHV0ZSBzaGFkb3cgbWF0cml4XG5cblx0XHRcdFx0c2hhZG93TWF0cml4LnNldChcblx0XHRcdFx0XHQwLjUsIDAuMCwgMC4wLCAwLjUsXG5cdFx0XHRcdFx0MC4wLCAwLjUsIDAuMCwgMC41LFxuXHRcdFx0XHRcdDAuMCwgMC4wLCAwLjUsIDAuNSxcblx0XHRcdFx0XHQwLjAsIDAuMCwgMC4wLCAxLjBcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRzaGFkb3dNYXRyaXgubXVsdGlwbHkoIHNoYWRvd0NhbWVyYS5wcm9qZWN0aW9uTWF0cml4ICk7XG5cdFx0XHRcdHNoYWRvd01hdHJpeC5tdWx0aXBseSggc2hhZG93Q2FtZXJhLm1hdHJpeFdvcmxkSW52ZXJzZSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggc2hhZG93Lm1hcCA9PT0gbnVsbCApIHtcblxuXHRcdFx0XHR2YXIgcGFycyA9IHsgbWluRmlsdGVyOiBOZWFyZXN0RmlsdGVyLCBtYWdGaWx0ZXI6IE5lYXJlc3RGaWx0ZXIsIGZvcm1hdDogUkdCQUZvcm1hdCB9O1xuXG5cdFx0XHRcdHNoYWRvdy5tYXAgPSBuZXcgV2ViR0xSZW5kZXJUYXJnZXQoIF9zaGFkb3dNYXBTaXplLngsIF9zaGFkb3dNYXBTaXplLnksIHBhcnMgKTtcblx0XHRcdFx0c2hhZG93Lm1hcC50ZXh0dXJlLm5hbWUgPSBsaWdodC5uYW1lICsgXCIuc2hhZG93TWFwXCI7XG5cblx0XHRcdFx0c2hhZG93Q2FtZXJhLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNoYWRvdy5pc1Nwb3RMaWdodFNoYWRvdyApIHtcblxuXHRcdFx0XHRzaGFkb3cudXBkYXRlKCBsaWdodCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBzaGFkb3dNYXAgPSBzaGFkb3cubWFwO1xuXG5cdFx0XHRfcmVuZGVyZXIuc2V0UmVuZGVyVGFyZ2V0KCBzaGFkb3dNYXAgKTtcblx0XHRcdF9yZW5kZXJlci5jbGVhcigpO1xuXG5cdFx0XHQvLyByZW5kZXIgc2hhZG93IG1hcCBmb3IgZWFjaCBjdWJlIGZhY2UgKGlmIG9tbmktZGlyZWN0aW9uYWwpIG9yXG5cdFx0XHQvLyBydW4gYSBzaW5nbGUgcGFzcyBpZiBub3RcblxuXHRcdFx0Zm9yICggdmFyIGZhY2UgPSAwOyBmYWNlIDwgZmFjZUNvdW50OyBmYWNlICsrICkge1xuXG5cdFx0XHRcdGlmICggaXNQb2ludExpZ2h0ICkge1xuXG5cdFx0XHRcdFx0X2xvb2tUYXJnZXQuY29weSggc2hhZG93Q2FtZXJhLnBvc2l0aW9uICk7XG5cdFx0XHRcdFx0X2xvb2tUYXJnZXQuYWRkKCBjdWJlRGlyZWN0aW9uc1sgZmFjZSBdICk7XG5cdFx0XHRcdFx0c2hhZG93Q2FtZXJhLnVwLmNvcHkoIGN1YmVVcHNbIGZhY2UgXSApO1xuXHRcdFx0XHRcdHNoYWRvd0NhbWVyYS5sb29rQXQoIF9sb29rVGFyZ2V0ICk7XG5cdFx0XHRcdFx0c2hhZG93Q2FtZXJhLnVwZGF0ZU1hdHJpeFdvcmxkKCk7XG5cdFx0XHRcdFx0c2hhZG93Q2FtZXJhLm1hdHJpeFdvcmxkSW52ZXJzZS5nZXRJbnZlcnNlKCBzaGFkb3dDYW1lcmEubWF0cml4V29ybGQgKTtcblxuXHRcdFx0XHRcdHZhciB2cERpbWVuc2lvbnMgPSBjdWJlMkRWaWV3UG9ydHNbIGZhY2UgXTtcblx0XHRcdFx0XHRfc3RhdGUudmlld3BvcnQoIHZwRGltZW5zaW9ucyApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyB1cGRhdGUgY2FtZXJhIG1hdHJpY2VzIGFuZCBmcnVzdHVtXG5cblx0XHRcdFx0X3Byb2pTY3JlZW5NYXRyaXgubXVsdGlwbHlNYXRyaWNlcyggc2hhZG93Q2FtZXJhLnByb2plY3Rpb25NYXRyaXgsIHNoYWRvd0NhbWVyYS5tYXRyaXhXb3JsZEludmVyc2UgKTtcblx0XHRcdFx0X2ZydXN0dW0uc2V0RnJvbU1hdHJpeCggX3Byb2pTY3JlZW5NYXRyaXggKTtcblxuXHRcdFx0XHQvLyBzZXQgb2JqZWN0IG1hdHJpY2VzICYgZnJ1c3R1bSBjdWxsaW5nXG5cblx0XHRcdFx0cmVuZGVyT2JqZWN0KCBzY2VuZSwgY2FtZXJhLCBzaGFkb3dDYW1lcmEsIGlzUG9pbnRMaWdodCApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHQvLyBSZXN0b3JlIEdMIHN0YXRlLlxuXHRcdHZhciBjbGVhckNvbG9yID0gX3JlbmRlcmVyLmdldENsZWFyQ29sb3IoKTtcblx0XHR2YXIgY2xlYXJBbHBoYSA9IF9yZW5kZXJlci5nZXRDbGVhckFscGhhKCk7XG5cdFx0X3JlbmRlcmVyLnNldENsZWFyQ29sb3IoIGNsZWFyQ29sb3IsIGNsZWFyQWxwaGEgKTtcblxuXHRcdHNjb3BlLm5lZWRzVXBkYXRlID0gZmFsc2U7XG5cblx0fTtcblxuXHRmdW5jdGlvbiBnZXREZXB0aE1hdGVyaWFsKCBvYmplY3QsIG1hdGVyaWFsLCBpc1BvaW50TGlnaHQsIGxpZ2h0UG9zaXRpb25Xb3JsZCApIHtcblxuXHRcdHZhciBnZW9tZXRyeSA9IG9iamVjdC5nZW9tZXRyeTtcblxuXHRcdHZhciByZXN1bHQgPSBudWxsO1xuXG5cdFx0dmFyIG1hdGVyaWFsVmFyaWFudHMgPSBfZGVwdGhNYXRlcmlhbHM7XG5cdFx0dmFyIGN1c3RvbU1hdGVyaWFsID0gb2JqZWN0LmN1c3RvbURlcHRoTWF0ZXJpYWw7XG5cblx0XHRpZiAoIGlzUG9pbnRMaWdodCApIHtcblxuXHRcdFx0bWF0ZXJpYWxWYXJpYW50cyA9IF9kaXN0YW5jZU1hdGVyaWFscztcblx0XHRcdGN1c3RvbU1hdGVyaWFsID0gb2JqZWN0LmN1c3RvbURpc3RhbmNlTWF0ZXJpYWw7XG5cblx0XHR9XG5cblx0XHRpZiAoICEgY3VzdG9tTWF0ZXJpYWwgKSB7XG5cblx0XHRcdHZhciB1c2VNb3JwaGluZyA9IGZhbHNlO1xuXG5cdFx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0XHRpZiAoIGdlb21ldHJ5ICYmIGdlb21ldHJ5LmlzQnVmZmVyR2VvbWV0cnkgKSB7XG5cblx0XHRcdFx0XHR1c2VNb3JwaGluZyA9IGdlb21ldHJ5Lm1vcnBoQXR0cmlidXRlcyAmJiBnZW9tZXRyeS5tb3JwaEF0dHJpYnV0ZXMucG9zaXRpb24gJiYgZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzLnBvc2l0aW9uLmxlbmd0aCA+IDA7XG5cblx0XHRcdFx0fSBlbHNlIGlmICggZ2VvbWV0cnkgJiYgZ2VvbWV0cnkuaXNHZW9tZXRyeSApIHtcblxuXHRcdFx0XHRcdHVzZU1vcnBoaW5nID0gZ2VvbWV0cnkubW9ycGhUYXJnZXRzICYmIGdlb21ldHJ5Lm1vcnBoVGFyZ2V0cy5sZW5ndGggPiAwO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG9iamVjdC5pc1NraW5uZWRNZXNoICYmIG1hdGVyaWFsLnNraW5uaW5nID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFNoYWRvd01hcDogVEhSRUUuU2tpbm5lZE1lc2ggd2l0aCBtYXRlcmlhbC5za2lubmluZyBzZXQgdG8gZmFsc2U6Jywgb2JqZWN0ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIHVzZVNraW5uaW5nID0gb2JqZWN0LmlzU2tpbm5lZE1lc2ggJiYgbWF0ZXJpYWwuc2tpbm5pbmc7XG5cblx0XHRcdHZhciB2YXJpYW50SW5kZXggPSAwO1xuXG5cdFx0XHRpZiAoIHVzZU1vcnBoaW5nICkgdmFyaWFudEluZGV4IHw9IF9Nb3JwaGluZ0ZsYWc7XG5cdFx0XHRpZiAoIHVzZVNraW5uaW5nICkgdmFyaWFudEluZGV4IHw9IF9Ta2lubmluZ0ZsYWc7XG5cblx0XHRcdHJlc3VsdCA9IG1hdGVyaWFsVmFyaWFudHNbIHZhcmlhbnRJbmRleCBdO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0cmVzdWx0ID0gY3VzdG9tTWF0ZXJpYWw7XG5cblx0XHR9XG5cblx0XHRpZiAoIF9yZW5kZXJlci5sb2NhbENsaXBwaW5nRW5hYmxlZCAmJlxuXHRcdFx0XHRtYXRlcmlhbC5jbGlwU2hhZG93cyA9PT0gdHJ1ZSAmJlxuXHRcdFx0XHRtYXRlcmlhbC5jbGlwcGluZ1BsYW5lcy5sZW5ndGggIT09IDAgKSB7XG5cblx0XHRcdC8vIGluIHRoaXMgY2FzZSB3ZSBuZWVkIGEgdW5pcXVlIG1hdGVyaWFsIGluc3RhbmNlIHJlZmxlY3RpbmcgdGhlXG5cdFx0XHQvLyBhcHByb3ByaWF0ZSBzdGF0ZVxuXG5cdFx0XHR2YXIga2V5QSA9IHJlc3VsdC51dWlkLCBrZXlCID0gbWF0ZXJpYWwudXVpZDtcblxuXHRcdFx0dmFyIG1hdGVyaWFsc0ZvclZhcmlhbnQgPSBfbWF0ZXJpYWxDYWNoZVsga2V5QSBdO1xuXG5cdFx0XHRpZiAoIG1hdGVyaWFsc0ZvclZhcmlhbnQgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRtYXRlcmlhbHNGb3JWYXJpYW50ID0ge307XG5cdFx0XHRcdF9tYXRlcmlhbENhY2hlWyBrZXlBIF0gPSBtYXRlcmlhbHNGb3JWYXJpYW50O1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBjYWNoZWRNYXRlcmlhbCA9IG1hdGVyaWFsc0ZvclZhcmlhbnRbIGtleUIgXTtcblxuXHRcdFx0aWYgKCBjYWNoZWRNYXRlcmlhbCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGNhY2hlZE1hdGVyaWFsID0gcmVzdWx0LmNsb25lKCk7XG5cdFx0XHRcdG1hdGVyaWFsc0ZvclZhcmlhbnRbIGtleUIgXSA9IGNhY2hlZE1hdGVyaWFsO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJlc3VsdCA9IGNhY2hlZE1hdGVyaWFsO1xuXG5cdFx0fVxuXG5cdFx0cmVzdWx0LnZpc2libGUgPSBtYXRlcmlhbC52aXNpYmxlO1xuXHRcdHJlc3VsdC53aXJlZnJhbWUgPSBtYXRlcmlhbC53aXJlZnJhbWU7XG5cblx0XHR2YXIgc2lkZSA9IG1hdGVyaWFsLnNpZGU7XG5cblx0XHRpZiAoIHNjb3BlLnJlbmRlclNpbmdsZVNpZGVkICYmIHNpZGUgPT0gRG91YmxlU2lkZSApIHtcblxuXHRcdFx0c2lkZSA9IEZyb250U2lkZTtcblxuXHRcdH1cblxuXHRcdGlmICggc2NvcGUucmVuZGVyUmV2ZXJzZVNpZGVkICkge1xuXG5cdFx0XHRpZiAoIHNpZGUgPT09IEZyb250U2lkZSApIHNpZGUgPSBCYWNrU2lkZTtcblx0XHRcdGVsc2UgaWYgKCBzaWRlID09PSBCYWNrU2lkZSApIHNpZGUgPSBGcm9udFNpZGU7XG5cblx0XHR9XG5cblx0XHRyZXN1bHQuc2lkZSA9IHNpZGU7XG5cblx0XHRyZXN1bHQuY2xpcFNoYWRvd3MgPSBtYXRlcmlhbC5jbGlwU2hhZG93cztcblx0XHRyZXN1bHQuY2xpcHBpbmdQbGFuZXMgPSBtYXRlcmlhbC5jbGlwcGluZ1BsYW5lcztcblxuXHRcdHJlc3VsdC53aXJlZnJhbWVMaW5ld2lkdGggPSBtYXRlcmlhbC53aXJlZnJhbWVMaW5ld2lkdGg7XG5cdFx0cmVzdWx0LmxpbmV3aWR0aCA9IG1hdGVyaWFsLmxpbmV3aWR0aDtcblxuXHRcdGlmICggaXNQb2ludExpZ2h0ICYmIHJlc3VsdC51bmlmb3Jtcy5saWdodFBvcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRyZXN1bHQudW5pZm9ybXMubGlnaHRQb3MudmFsdWUuY29weSggbGlnaHRQb3NpdGlvbldvcmxkICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdH1cblxuXHRmdW5jdGlvbiByZW5kZXJPYmplY3QoIG9iamVjdCwgY2FtZXJhLCBzaGFkb3dDYW1lcmEsIGlzUG9pbnRMaWdodCApIHtcblxuXHRcdGlmICggb2JqZWN0LnZpc2libGUgPT09IGZhbHNlICkgcmV0dXJuO1xuXG5cdFx0dmFyIHZpc2libGUgPSBvYmplY3QubGF5ZXJzLnRlc3QoIGNhbWVyYS5sYXllcnMgKTtcblxuXHRcdGlmICggdmlzaWJsZSAmJiAoIG9iamVjdC5pc01lc2ggfHwgb2JqZWN0LmlzTGluZSB8fCBvYmplY3QuaXNQb2ludHMgKSApIHtcblxuXHRcdFx0aWYgKCBvYmplY3QuY2FzdFNoYWRvdyAmJiAoICEgb2JqZWN0LmZydXN0dW1DdWxsZWQgfHwgX2ZydXN0dW0uaW50ZXJzZWN0c09iamVjdCggb2JqZWN0ICkgKSApIHtcblxuXHRcdFx0XHRvYmplY3QubW9kZWxWaWV3TWF0cml4Lm11bHRpcGx5TWF0cmljZXMoIHNoYWRvd0NhbWVyYS5tYXRyaXhXb3JsZEludmVyc2UsIG9iamVjdC5tYXRyaXhXb3JsZCApO1xuXG5cdFx0XHRcdHZhciBnZW9tZXRyeSA9IF9vYmplY3RzLnVwZGF0ZSggb2JqZWN0ICk7XG5cdFx0XHRcdHZhciBtYXRlcmlhbCA9IG9iamVjdC5tYXRlcmlhbDtcblxuXHRcdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG1hdGVyaWFsICkgKSB7XG5cblx0XHRcdFx0XHR2YXIgZ3JvdXBzID0gZ2VvbWV0cnkuZ3JvdXBzO1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGsgPSAwLCBrbCA9IGdyb3Vwcy5sZW5ndGg7IGsgPCBrbDsgayArKyApIHtcblxuXHRcdFx0XHRcdFx0dmFyIGdyb3VwID0gZ3JvdXBzWyBrIF07XG5cdFx0XHRcdFx0XHR2YXIgZ3JvdXBNYXRlcmlhbCA9IG1hdGVyaWFsWyBncm91cC5tYXRlcmlhbEluZGV4IF07XG5cblx0XHRcdFx0XHRcdGlmICggZ3JvdXBNYXRlcmlhbCAmJiBncm91cE1hdGVyaWFsLnZpc2libGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0dmFyIGRlcHRoTWF0ZXJpYWwgPSBnZXREZXB0aE1hdGVyaWFsKCBvYmplY3QsIGdyb3VwTWF0ZXJpYWwsIGlzUG9pbnRMaWdodCwgX2xpZ2h0UG9zaXRpb25Xb3JsZCApO1xuXHRcdFx0XHRcdFx0XHRfcmVuZGVyZXIucmVuZGVyQnVmZmVyRGlyZWN0KCBzaGFkb3dDYW1lcmEsIG51bGwsIGdlb21ldHJ5LCBkZXB0aE1hdGVyaWFsLCBvYmplY3QsIGdyb3VwICk7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC52aXNpYmxlICkge1xuXG5cdFx0XHRcdFx0dmFyIGRlcHRoTWF0ZXJpYWwgPSBnZXREZXB0aE1hdGVyaWFsKCBvYmplY3QsIG1hdGVyaWFsLCBpc1BvaW50TGlnaHQsIF9saWdodFBvc2l0aW9uV29ybGQgKTtcblx0XHRcdFx0XHRfcmVuZGVyZXIucmVuZGVyQnVmZmVyRGlyZWN0KCBzaGFkb3dDYW1lcmEsIG51bGwsIGdlb21ldHJ5LCBkZXB0aE1hdGVyaWFsLCBvYmplY3QsIG51bGwgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHZhciBjaGlsZHJlbiA9IG9iamVjdC5jaGlsZHJlbjtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHJlbmRlck9iamVjdCggY2hpbGRyZW5bIGkgXSwgY2FtZXJhLCBzaGFkb3dDYW1lcmEsIGlzUG9pbnRMaWdodCApO1xuXG5cdFx0fVxuXG5cdH1cblxufVxuXG4vKipcbiAqIEBhdXRob3IgYmhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW9cbiAqL1xuXG5mdW5jdGlvbiBSYXkoIG9yaWdpbiwgZGlyZWN0aW9uICkge1xuXG5cdHRoaXMub3JpZ2luID0gKCBvcmlnaW4gIT09IHVuZGVmaW5lZCApID8gb3JpZ2luIDogbmV3IFZlY3RvcjMoKTtcblx0dGhpcy5kaXJlY3Rpb24gPSAoIGRpcmVjdGlvbiAhPT0gdW5kZWZpbmVkICkgPyBkaXJlY3Rpb24gOiBuZXcgVmVjdG9yMygpO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFJheS5wcm90b3R5cGUsIHtcblxuXHRzZXQ6IGZ1bmN0aW9uICggb3JpZ2luLCBkaXJlY3Rpb24gKSB7XG5cblx0XHR0aGlzLm9yaWdpbi5jb3B5KCBvcmlnaW4gKTtcblx0XHR0aGlzLmRpcmVjdGlvbi5jb3B5KCBkaXJlY3Rpb24gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggcmF5ICkge1xuXG5cdFx0dGhpcy5vcmlnaW4uY29weSggcmF5Lm9yaWdpbiApO1xuXHRcdHRoaXMuZGlyZWN0aW9uLmNvcHkoIHJheS5kaXJlY3Rpb24gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YXQ6IGZ1bmN0aW9uICggdCwgb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiByZXN1bHQuY29weSggdGhpcy5kaXJlY3Rpb24gKS5tdWx0aXBseVNjYWxhciggdCApLmFkZCggdGhpcy5vcmlnaW4gKTtcblxuXHR9LFxuXG5cdGxvb2tBdDogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0dGhpcy5kaXJlY3Rpb24uY29weSggdiApLnN1YiggdGhpcy5vcmlnaW4gKS5ub3JtYWxpemUoKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0cmVjYXN0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHJlY2FzdCggdCApIHtcblxuXHRcdFx0dGhpcy5vcmlnaW4uY29weSggdGhpcy5hdCggdCwgdjEgKSApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGNsb3Nlc3RQb2ludFRvUG9pbnQ6IGZ1bmN0aW9uICggcG9pbnQsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cdFx0cmVzdWx0LnN1YlZlY3RvcnMoIHBvaW50LCB0aGlzLm9yaWdpbiApO1xuXHRcdHZhciBkaXJlY3Rpb25EaXN0YW5jZSA9IHJlc3VsdC5kb3QoIHRoaXMuZGlyZWN0aW9uICk7XG5cblx0XHRpZiAoIGRpcmVjdGlvbkRpc3RhbmNlIDwgMCApIHtcblxuXHRcdFx0cmV0dXJuIHJlc3VsdC5jb3B5KCB0aGlzLm9yaWdpbiApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdC5jb3B5KCB0aGlzLmRpcmVjdGlvbiApLm11bHRpcGx5U2NhbGFyKCBkaXJlY3Rpb25EaXN0YW5jZSApLmFkZCggdGhpcy5vcmlnaW4gKTtcblxuXHR9LFxuXG5cdGRpc3RhbmNlVG9Qb2ludDogZnVuY3Rpb24gKCBwb2ludCApIHtcblxuXHRcdHJldHVybiBNYXRoLnNxcnQoIHRoaXMuZGlzdGFuY2VTcVRvUG9pbnQoIHBvaW50ICkgKTtcblxuXHR9LFxuXG5cdGRpc3RhbmNlU3FUb1BvaW50OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGRpc3RhbmNlU3FUb1BvaW50KCBwb2ludCApIHtcblxuXHRcdFx0dmFyIGRpcmVjdGlvbkRpc3RhbmNlID0gdjEuc3ViVmVjdG9ycyggcG9pbnQsIHRoaXMub3JpZ2luICkuZG90KCB0aGlzLmRpcmVjdGlvbiApO1xuXG5cdFx0XHQvLyBwb2ludCBiZWhpbmQgdGhlIHJheVxuXG5cdFx0XHRpZiAoIGRpcmVjdGlvbkRpc3RhbmNlIDwgMCApIHtcblxuXHRcdFx0XHRyZXR1cm4gdGhpcy5vcmlnaW4uZGlzdGFuY2VUb1NxdWFyZWQoIHBvaW50ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0djEuY29weSggdGhpcy5kaXJlY3Rpb24gKS5tdWx0aXBseVNjYWxhciggZGlyZWN0aW9uRGlzdGFuY2UgKS5hZGQoIHRoaXMub3JpZ2luICk7XG5cblx0XHRcdHJldHVybiB2MS5kaXN0YW5jZVRvU3F1YXJlZCggcG9pbnQgKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGRpc3RhbmNlU3FUb1NlZ21lbnQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBzZWdDZW50ZXIgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBzZWdEaXIgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBkaWZmID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBkaXN0YW5jZVNxVG9TZWdtZW50KCB2MCwgdjEsIG9wdGlvbmFsUG9pbnRPblJheSwgb3B0aW9uYWxQb2ludE9uU2VnbWVudCApIHtcblxuXHRcdFx0Ly8gZnJvbSBodHRwOi8vd3d3Lmdlb21ldHJpY3Rvb2xzLmNvbS9HVEVuZ2luZS9JbmNsdWRlL01hdGhlbWF0aWNzL0d0ZURpc3RSYXlTZWdtZW50Lmhcblx0XHRcdC8vIEl0IHJldHVybnMgdGhlIG1pbiBkaXN0YW5jZSBiZXR3ZWVuIHRoZSByYXkgYW5kIHRoZSBzZWdtZW50XG5cdFx0XHQvLyBkZWZpbmVkIGJ5IHYwIGFuZCB2MVxuXHRcdFx0Ly8gSXQgY2FuIGFsc28gc2V0IHR3byBvcHRpb25hbCB0YXJnZXRzIDpcblx0XHRcdC8vIC0gVGhlIGNsb3Nlc3QgcG9pbnQgb24gdGhlIHJheVxuXHRcdFx0Ly8gLSBUaGUgY2xvc2VzdCBwb2ludCBvbiB0aGUgc2VnbWVudFxuXG5cdFx0XHRzZWdDZW50ZXIuY29weSggdjAgKS5hZGQoIHYxICkubXVsdGlwbHlTY2FsYXIoIDAuNSApO1xuXHRcdFx0c2VnRGlyLmNvcHkoIHYxICkuc3ViKCB2MCApLm5vcm1hbGl6ZSgpO1xuXHRcdFx0ZGlmZi5jb3B5KCB0aGlzLm9yaWdpbiApLnN1Yiggc2VnQ2VudGVyICk7XG5cblx0XHRcdHZhciBzZWdFeHRlbnQgPSB2MC5kaXN0YW5jZVRvKCB2MSApICogMC41O1xuXHRcdFx0dmFyIGEwMSA9IC0gdGhpcy5kaXJlY3Rpb24uZG90KCBzZWdEaXIgKTtcblx0XHRcdHZhciBiMCA9IGRpZmYuZG90KCB0aGlzLmRpcmVjdGlvbiApO1xuXHRcdFx0dmFyIGIxID0gLSBkaWZmLmRvdCggc2VnRGlyICk7XG5cdFx0XHR2YXIgYyA9IGRpZmYubGVuZ3RoU3EoKTtcblx0XHRcdHZhciBkZXQgPSBNYXRoLmFicyggMSAtIGEwMSAqIGEwMSApO1xuXHRcdFx0dmFyIHMwLCBzMSwgc3FyRGlzdCwgZXh0RGV0O1xuXG5cdFx0XHRpZiAoIGRldCA+IDAgKSB7XG5cblx0XHRcdFx0Ly8gVGhlIHJheSBhbmQgc2VnbWVudCBhcmUgbm90IHBhcmFsbGVsLlxuXG5cdFx0XHRcdHMwID0gYTAxICogYjEgLSBiMDtcblx0XHRcdFx0czEgPSBhMDEgKiBiMCAtIGIxO1xuXHRcdFx0XHRleHREZXQgPSBzZWdFeHRlbnQgKiBkZXQ7XG5cblx0XHRcdFx0aWYgKCBzMCA+PSAwICkge1xuXG5cdFx0XHRcdFx0aWYgKCBzMSA+PSAtIGV4dERldCApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBzMSA8PSBleHREZXQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gcmVnaW9uIDBcblx0XHRcdFx0XHRcdFx0Ly8gTWluaW11bSBhdCBpbnRlcmlvciBwb2ludHMgb2YgcmF5IGFuZCBzZWdtZW50LlxuXG5cdFx0XHRcdFx0XHRcdHZhciBpbnZEZXQgPSAxIC8gZGV0O1xuXHRcdFx0XHRcdFx0XHRzMCAqPSBpbnZEZXQ7XG5cdFx0XHRcdFx0XHRcdHMxICo9IGludkRldDtcblx0XHRcdFx0XHRcdFx0c3FyRGlzdCA9IHMwICogKCBzMCArIGEwMSAqIHMxICsgMiAqIGIwICkgKyBzMSAqICggYTAxICogczAgKyBzMSArIDIgKiBiMSApICsgYztcblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyByZWdpb24gMVxuXG5cdFx0XHRcdFx0XHRcdHMxID0gc2VnRXh0ZW50O1xuXHRcdFx0XHRcdFx0XHRzMCA9IE1hdGgubWF4KCAwLCAtICggYTAxICogczEgKyBiMCApICk7XG5cdFx0XHRcdFx0XHRcdHNxckRpc3QgPSAtIHMwICogczAgKyBzMSAqICggczEgKyAyICogYjEgKSArIGM7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIHJlZ2lvbiA1XG5cblx0XHRcdFx0XHRcdHMxID0gLSBzZWdFeHRlbnQ7XG5cdFx0XHRcdFx0XHRzMCA9IE1hdGgubWF4KCAwLCAtICggYTAxICogczEgKyBiMCApICk7XG5cdFx0XHRcdFx0XHRzcXJEaXN0ID0gLSBzMCAqIHMwICsgczEgKiAoIHMxICsgMiAqIGIxICkgKyBjO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRpZiAoIHMxIDw9IC0gZXh0RGV0ICkge1xuXG5cdFx0XHRcdFx0XHQvLyByZWdpb24gNFxuXG5cdFx0XHRcdFx0XHRzMCA9IE1hdGgubWF4KCAwLCAtICggLSBhMDEgKiBzZWdFeHRlbnQgKyBiMCApICk7XG5cdFx0XHRcdFx0XHRzMSA9ICggczAgPiAwICkgPyAtIHNlZ0V4dGVudCA6IE1hdGgubWluKCBNYXRoLm1heCggLSBzZWdFeHRlbnQsIC0gYjEgKSwgc2VnRXh0ZW50ICk7XG5cdFx0XHRcdFx0XHRzcXJEaXN0ID0gLSBzMCAqIHMwICsgczEgKiAoIHMxICsgMiAqIGIxICkgKyBjO1xuXG5cdFx0XHRcdFx0fSBlbHNlIGlmICggczEgPD0gZXh0RGV0ICkge1xuXG5cdFx0XHRcdFx0XHQvLyByZWdpb24gM1xuXG5cdFx0XHRcdFx0XHRzMCA9IDA7XG5cdFx0XHRcdFx0XHRzMSA9IE1hdGgubWluKCBNYXRoLm1heCggLSBzZWdFeHRlbnQsIC0gYjEgKSwgc2VnRXh0ZW50ICk7XG5cdFx0XHRcdFx0XHRzcXJEaXN0ID0gczEgKiAoIHMxICsgMiAqIGIxICkgKyBjO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0Ly8gcmVnaW9uIDJcblxuXHRcdFx0XHRcdFx0czAgPSBNYXRoLm1heCggMCwgLSAoIGEwMSAqIHNlZ0V4dGVudCArIGIwICkgKTtcblx0XHRcdFx0XHRcdHMxID0gKCBzMCA+IDAgKSA/IHNlZ0V4dGVudCA6IE1hdGgubWluKCBNYXRoLm1heCggLSBzZWdFeHRlbnQsIC0gYjEgKSwgc2VnRXh0ZW50ICk7XG5cdFx0XHRcdFx0XHRzcXJEaXN0ID0gLSBzMCAqIHMwICsgczEgKiAoIHMxICsgMiAqIGIxICkgKyBjO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBSYXkgYW5kIHNlZ21lbnQgYXJlIHBhcmFsbGVsLlxuXG5cdFx0XHRcdHMxID0gKCBhMDEgPiAwICkgPyAtIHNlZ0V4dGVudCA6IHNlZ0V4dGVudDtcblx0XHRcdFx0czAgPSBNYXRoLm1heCggMCwgLSAoIGEwMSAqIHMxICsgYjAgKSApO1xuXHRcdFx0XHRzcXJEaXN0ID0gLSBzMCAqIHMwICsgczEgKiAoIHMxICsgMiAqIGIxICkgKyBjO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggb3B0aW9uYWxQb2ludE9uUmF5ICkge1xuXG5cdFx0XHRcdG9wdGlvbmFsUG9pbnRPblJheS5jb3B5KCB0aGlzLmRpcmVjdGlvbiApLm11bHRpcGx5U2NhbGFyKCBzMCApLmFkZCggdGhpcy5vcmlnaW4gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG9wdGlvbmFsUG9pbnRPblNlZ21lbnQgKSB7XG5cblx0XHRcdFx0b3B0aW9uYWxQb2ludE9uU2VnbWVudC5jb3B5KCBzZWdEaXIgKS5tdWx0aXBseVNjYWxhciggczEgKS5hZGQoIHNlZ0NlbnRlciApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBzcXJEaXN0O1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0aW50ZXJzZWN0U3BoZXJlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGludGVyc2VjdFNwaGVyZSggc3BoZXJlLCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdFx0djEuc3ViVmVjdG9ycyggc3BoZXJlLmNlbnRlciwgdGhpcy5vcmlnaW4gKTtcblx0XHRcdHZhciB0Y2EgPSB2MS5kb3QoIHRoaXMuZGlyZWN0aW9uICk7XG5cdFx0XHR2YXIgZDIgPSB2MS5kb3QoIHYxICkgLSB0Y2EgKiB0Y2E7XG5cdFx0XHR2YXIgcmFkaXVzMiA9IHNwaGVyZS5yYWRpdXMgKiBzcGhlcmUucmFkaXVzO1xuXG5cdFx0XHRpZiAoIGQyID4gcmFkaXVzMiApIHJldHVybiBudWxsO1xuXG5cdFx0XHR2YXIgdGhjID0gTWF0aC5zcXJ0KCByYWRpdXMyIC0gZDIgKTtcblxuXHRcdFx0Ly8gdDAgPSBmaXJzdCBpbnRlcnNlY3QgcG9pbnQgLSBlbnRyYW5jZSBvbiBmcm9udCBvZiBzcGhlcmVcblx0XHRcdHZhciB0MCA9IHRjYSAtIHRoYztcblxuXHRcdFx0Ly8gdDEgPSBzZWNvbmQgaW50ZXJzZWN0IHBvaW50IC0gZXhpdCBwb2ludCBvbiBiYWNrIG9mIHNwaGVyZVxuXHRcdFx0dmFyIHQxID0gdGNhICsgdGhjO1xuXG5cdFx0XHQvLyB0ZXN0IHRvIHNlZSBpZiBib3RoIHQwIGFuZCB0MSBhcmUgYmVoaW5kIHRoZSByYXkgLSBpZiBzbywgcmV0dXJuIG51bGxcblx0XHRcdGlmICggdDAgPCAwICYmIHQxIDwgMCApIHJldHVybiBudWxsO1xuXG5cdFx0XHQvLyB0ZXN0IHRvIHNlZSBpZiB0MCBpcyBiZWhpbmQgdGhlIHJheTpcblx0XHRcdC8vIGlmIGl0IGlzLCB0aGUgcmF5IGlzIGluc2lkZSB0aGUgc3BoZXJlLCBzbyByZXR1cm4gdGhlIHNlY29uZCBleGl0IHBvaW50IHNjYWxlZCBieSB0MSxcblx0XHRcdC8vIGluIG9yZGVyIHRvIGFsd2F5cyByZXR1cm4gYW4gaW50ZXJzZWN0IHBvaW50IHRoYXQgaXMgaW4gZnJvbnQgb2YgdGhlIHJheS5cblx0XHRcdGlmICggdDAgPCAwICkgcmV0dXJuIHRoaXMuYXQoIHQxLCBvcHRpb25hbFRhcmdldCApO1xuXG5cdFx0XHQvLyBlbHNlIHQwIGlzIGluIGZyb250IG9mIHRoZSByYXksIHNvIHJldHVybiB0aGUgZmlyc3QgY29sbGlzaW9uIHBvaW50IHNjYWxlZCBieSB0MFxuXHRcdFx0cmV0dXJuIHRoaXMuYXQoIHQwLCBvcHRpb25hbFRhcmdldCApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0aW50ZXJzZWN0c1NwaGVyZTogZnVuY3Rpb24gKCBzcGhlcmUgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5kaXN0YW5jZVRvUG9pbnQoIHNwaGVyZS5jZW50ZXIgKSA8PSBzcGhlcmUucmFkaXVzO1xuXG5cdH0sXG5cblx0ZGlzdGFuY2VUb1BsYW5lOiBmdW5jdGlvbiAoIHBsYW5lICkge1xuXG5cdFx0dmFyIGRlbm9taW5hdG9yID0gcGxhbmUubm9ybWFsLmRvdCggdGhpcy5kaXJlY3Rpb24gKTtcblxuXHRcdGlmICggZGVub21pbmF0b3IgPT09IDAgKSB7XG5cblx0XHRcdC8vIGxpbmUgaXMgY29wbGFuYXIsIHJldHVybiBvcmlnaW5cblx0XHRcdGlmICggcGxhbmUuZGlzdGFuY2VUb1BvaW50KCB0aGlzLm9yaWdpbiApID09PSAwICkge1xuXG5cdFx0XHRcdHJldHVybiAwO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIE51bGwgaXMgcHJlZmVyYWJsZSB0byB1bmRlZmluZWQgc2luY2UgdW5kZWZpbmVkIG1lYW5zLi4uLiBpdCBpcyB1bmRlZmluZWRcblxuXHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHR9XG5cblx0XHR2YXIgdCA9IC0gKCB0aGlzLm9yaWdpbi5kb3QoIHBsYW5lLm5vcm1hbCApICsgcGxhbmUuY29uc3RhbnQgKSAvIGRlbm9taW5hdG9yO1xuXG5cdFx0Ly8gUmV0dXJuIGlmIHRoZSByYXkgbmV2ZXIgaW50ZXJzZWN0cyB0aGUgcGxhbmVcblxuXHRcdHJldHVybiB0ID49IDAgPyB0IDogIG51bGw7XG5cblx0fSxcblxuXHRpbnRlcnNlY3RQbGFuZTogZnVuY3Rpb24gKCBwbGFuZSwgb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHR2YXIgdCA9IHRoaXMuZGlzdGFuY2VUb1BsYW5lKCBwbGFuZSApO1xuXG5cdFx0aWYgKCB0ID09PSBudWxsICkge1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmF0KCB0LCBvcHRpb25hbFRhcmdldCApO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0c1BsYW5lOiBmdW5jdGlvbiAoIHBsYW5lICkge1xuXG5cdFx0Ly8gY2hlY2sgaWYgdGhlIHJheSBsaWVzIG9uIHRoZSBwbGFuZSBmaXJzdFxuXG5cdFx0dmFyIGRpc3RUb1BvaW50ID0gcGxhbmUuZGlzdGFuY2VUb1BvaW50KCB0aGlzLm9yaWdpbiApO1xuXG5cdFx0aWYgKCBkaXN0VG9Qb2ludCA9PT0gMCApIHtcblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cblx0XHR9XG5cblx0XHR2YXIgZGVub21pbmF0b3IgPSBwbGFuZS5ub3JtYWwuZG90KCB0aGlzLmRpcmVjdGlvbiApO1xuXG5cdFx0aWYgKCBkZW5vbWluYXRvciAqIGRpc3RUb1BvaW50IDwgMCApIHtcblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cblx0XHR9XG5cblx0XHQvLyByYXkgb3JpZ2luIGlzIGJlaGluZCB0aGUgcGxhbmUgKGFuZCBpcyBwb2ludGluZyBiZWhpbmQgaXQpXG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cblx0fSxcblxuXHRpbnRlcnNlY3RCb3g6IGZ1bmN0aW9uICggYm94LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciB0bWluLCB0bWF4LCB0eW1pbiwgdHltYXgsIHR6bWluLCB0em1heDtcblxuXHRcdHZhciBpbnZkaXJ4ID0gMSAvIHRoaXMuZGlyZWN0aW9uLngsXG5cdFx0XHRpbnZkaXJ5ID0gMSAvIHRoaXMuZGlyZWN0aW9uLnksXG5cdFx0XHRpbnZkaXJ6ID0gMSAvIHRoaXMuZGlyZWN0aW9uLno7XG5cblx0XHR2YXIgb3JpZ2luID0gdGhpcy5vcmlnaW47XG5cblx0XHRpZiAoIGludmRpcnggPj0gMCApIHtcblxuXHRcdFx0dG1pbiA9ICggYm94Lm1pbi54IC0gb3JpZ2luLnggKSAqIGludmRpcng7XG5cdFx0XHR0bWF4ID0gKCBib3gubWF4LnggLSBvcmlnaW4ueCApICogaW52ZGlyeDtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRtaW4gPSAoIGJveC5tYXgueCAtIG9yaWdpbi54ICkgKiBpbnZkaXJ4O1xuXHRcdFx0dG1heCA9ICggYm94Lm1pbi54IC0gb3JpZ2luLnggKSAqIGludmRpcng7XG5cblx0XHR9XG5cblx0XHRpZiAoIGludmRpcnkgPj0gMCApIHtcblxuXHRcdFx0dHltaW4gPSAoIGJveC5taW4ueSAtIG9yaWdpbi55ICkgKiBpbnZkaXJ5O1xuXHRcdFx0dHltYXggPSAoIGJveC5tYXgueSAtIG9yaWdpbi55ICkgKiBpbnZkaXJ5O1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dHltaW4gPSAoIGJveC5tYXgueSAtIG9yaWdpbi55ICkgKiBpbnZkaXJ5O1xuXHRcdFx0dHltYXggPSAoIGJveC5taW4ueSAtIG9yaWdpbi55ICkgKiBpbnZkaXJ5O1xuXG5cdFx0fVxuXG5cdFx0aWYgKCAoIHRtaW4gPiB0eW1heCApIHx8ICggdHltaW4gPiB0bWF4ICkgKSByZXR1cm4gbnVsbDtcblxuXHRcdC8vIFRoZXNlIGxpbmVzIGFsc28gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRtaW4gb3IgdG1heCBpcyBOYU5cblx0XHQvLyAocmVzdWx0IG9mIDAgKiBJbmZpbml0eSkuIHggIT09IHggcmV0dXJucyB0cnVlIGlmIHggaXMgTmFOXG5cblx0XHRpZiAoIHR5bWluID4gdG1pbiB8fCB0bWluICE9PSB0bWluICkgdG1pbiA9IHR5bWluO1xuXG5cdFx0aWYgKCB0eW1heCA8IHRtYXggfHwgdG1heCAhPT0gdG1heCApIHRtYXggPSB0eW1heDtcblxuXHRcdGlmICggaW52ZGlyeiA+PSAwICkge1xuXG5cdFx0XHR0em1pbiA9ICggYm94Lm1pbi56IC0gb3JpZ2luLnogKSAqIGludmRpcno7XG5cdFx0XHR0em1heCA9ICggYm94Lm1heC56IC0gb3JpZ2luLnogKSAqIGludmRpcno7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHR0em1pbiA9ICggYm94Lm1heC56IC0gb3JpZ2luLnogKSAqIGludmRpcno7XG5cdFx0XHR0em1heCA9ICggYm94Lm1pbi56IC0gb3JpZ2luLnogKSAqIGludmRpcno7XG5cblx0XHR9XG5cblx0XHRpZiAoICggdG1pbiA+IHR6bWF4ICkgfHwgKCB0em1pbiA+IHRtYXggKSApIHJldHVybiBudWxsO1xuXG5cdFx0aWYgKCB0em1pbiA+IHRtaW4gfHwgdG1pbiAhPT0gdG1pbiApIHRtaW4gPSB0em1pbjtcblxuXHRcdGlmICggdHptYXggPCB0bWF4IHx8IHRtYXggIT09IHRtYXggKSB0bWF4ID0gdHptYXg7XG5cblx0XHQvL3JldHVybiBwb2ludCBjbG9zZXN0IHRvIHRoZSByYXkgKHBvc2l0aXZlIHNpZGUpXG5cblx0XHRpZiAoIHRtYXggPCAwICkgcmV0dXJuIG51bGw7XG5cblx0XHRyZXR1cm4gdGhpcy5hdCggdG1pbiA+PSAwID8gdG1pbiA6IHRtYXgsIG9wdGlvbmFsVGFyZ2V0ICk7XG5cblx0fSxcblxuXHRpbnRlcnNlY3RzQm94OiAoIGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2ID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBpbnRlcnNlY3RzQm94KCBib3ggKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLmludGVyc2VjdEJveCggYm94LCB2ICkgIT09IG51bGw7XG5cblx0XHR9O1xuXG5cdH0gKSgpLFxuXG5cdGludGVyc2VjdFRyaWFuZ2xlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyBDb21wdXRlIHRoZSBvZmZzZXQgb3JpZ2luLCBlZGdlcywgYW5kIG5vcm1hbC5cblx0XHR2YXIgZGlmZiA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIGVkZ2UxID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgZWRnZTIgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBub3JtYWwgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGludGVyc2VjdFRyaWFuZ2xlKCBhLCBiLCBjLCBiYWNrZmFjZUN1bGxpbmcsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0XHQvLyBmcm9tIGh0dHA6Ly93d3cuZ2VvbWV0cmljdG9vbHMuY29tL0dURW5naW5lL0luY2x1ZGUvTWF0aGVtYXRpY3MvR3RlSW50clJheTNUcmlhbmdsZTMuaFxuXG5cdFx0XHRlZGdlMS5zdWJWZWN0b3JzKCBiLCBhICk7XG5cdFx0XHRlZGdlMi5zdWJWZWN0b3JzKCBjLCBhICk7XG5cdFx0XHRub3JtYWwuY3Jvc3NWZWN0b3JzKCBlZGdlMSwgZWRnZTIgKTtcblxuXHRcdFx0Ly8gU29sdmUgUSArIHQqRCA9IGIxKkUxICsgYjIqRTIgKFEgPSBrRGlmZiwgRCA9IHJheSBkaXJlY3Rpb24sXG5cdFx0XHQvLyBFMSA9IGtFZGdlMSwgRTIgPSBrRWRnZTIsIE4gPSBDcm9zcyhFMSxFMikpIGJ5XG5cdFx0XHQvLyAgIHxEb3QoRCxOKXwqYjEgPSBzaWduKERvdChELE4pKSpEb3QoRCxDcm9zcyhRLEUyKSlcblx0XHRcdC8vICAgfERvdChELE4pfCpiMiA9IHNpZ24oRG90KEQsTikpKkRvdChELENyb3NzKEUxLFEpKVxuXHRcdFx0Ly8gICB8RG90KEQsTil8KnQgPSAtc2lnbihEb3QoRCxOKSkqRG90KFEsTilcblx0XHRcdHZhciBEZE4gPSB0aGlzLmRpcmVjdGlvbi5kb3QoIG5vcm1hbCApO1xuXHRcdFx0dmFyIHNpZ247XG5cblx0XHRcdGlmICggRGROID4gMCApIHtcblxuXHRcdFx0XHRpZiAoIGJhY2tmYWNlQ3VsbGluZyApIHJldHVybiBudWxsO1xuXHRcdFx0XHRzaWduID0gMTtcblxuXHRcdFx0fSBlbHNlIGlmICggRGROIDwgMCApIHtcblxuXHRcdFx0XHRzaWduID0gLSAxO1xuXHRcdFx0XHREZE4gPSAtIERkTjtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdFx0fVxuXG5cdFx0XHRkaWZmLnN1YlZlY3RvcnMoIHRoaXMub3JpZ2luLCBhICk7XG5cdFx0XHR2YXIgRGRReEUyID0gc2lnbiAqIHRoaXMuZGlyZWN0aW9uLmRvdCggZWRnZTIuY3Jvc3NWZWN0b3JzKCBkaWZmLCBlZGdlMiApICk7XG5cblx0XHRcdC8vIGIxIDwgMCwgbm8gaW50ZXJzZWN0aW9uXG5cdFx0XHRpZiAoIERkUXhFMiA8IDAgKSB7XG5cblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIERkRTF4USA9IHNpZ24gKiB0aGlzLmRpcmVjdGlvbi5kb3QoIGVkZ2UxLmNyb3NzKCBkaWZmICkgKTtcblxuXHRcdFx0Ly8gYjIgPCAwLCBubyBpbnRlcnNlY3Rpb25cblx0XHRcdGlmICggRGRFMXhRIDwgMCApIHtcblxuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBiMStiMiA+IDEsIG5vIGludGVyc2VjdGlvblxuXHRcdFx0aWYgKCBEZFF4RTIgKyBEZEUxeFEgPiBEZE4gKSB7XG5cblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gTGluZSBpbnRlcnNlY3RzIHRyaWFuZ2xlLCBjaGVjayBpZiByYXkgZG9lcy5cblx0XHRcdHZhciBRZE4gPSAtIHNpZ24gKiBkaWZmLmRvdCggbm9ybWFsICk7XG5cblx0XHRcdC8vIHQgPCAwLCBubyBpbnRlcnNlY3Rpb25cblx0XHRcdGlmICggUWROIDwgMCApIHtcblxuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSYXkgaW50ZXJzZWN0cyB0cmlhbmdsZS5cblx0XHRcdHJldHVybiB0aGlzLmF0KCBRZE4gLyBEZE4sIG9wdGlvbmFsVGFyZ2V0ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRhcHBseU1hdHJpeDQ6IGZ1bmN0aW9uICggbWF0cml4NCApIHtcblxuXHRcdHRoaXMuZGlyZWN0aW9uLmFkZCggdGhpcy5vcmlnaW4gKS5hcHBseU1hdHJpeDQoIG1hdHJpeDQgKTtcblx0XHR0aGlzLm9yaWdpbi5hcHBseU1hdHJpeDQoIG1hdHJpeDQgKTtcblx0XHR0aGlzLmRpcmVjdGlvbi5zdWIoIHRoaXMub3JpZ2luICk7XG5cdFx0dGhpcy5kaXJlY3Rpb24ubm9ybWFsaXplKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGVxdWFsczogZnVuY3Rpb24gKCByYXkgKSB7XG5cblx0XHRyZXR1cm4gcmF5Lm9yaWdpbi5lcXVhbHMoIHRoaXMub3JpZ2luICkgJiYgcmF5LmRpcmVjdGlvbi5lcXVhbHMoIHRoaXMuZGlyZWN0aW9uICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICovXG5cbmZ1bmN0aW9uIEV1bGVyKCB4LCB5LCB6LCBvcmRlciApIHtcblxuXHR0aGlzLl94ID0geCB8fCAwO1xuXHR0aGlzLl95ID0geSB8fCAwO1xuXHR0aGlzLl96ID0geiB8fCAwO1xuXHR0aGlzLl9vcmRlciA9IG9yZGVyIHx8IEV1bGVyLkRlZmF1bHRPcmRlcjtcblxufVxuXG5FdWxlci5Sb3RhdGlvbk9yZGVycyA9IFsgJ1hZWicsICdZWlgnLCAnWlhZJywgJ1haWScsICdZWFonLCAnWllYJyBdO1xuXG5FdWxlci5EZWZhdWx0T3JkZXIgPSAnWFlaJztcblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIEV1bGVyLnByb3RvdHlwZSwge1xuXG5cdHg6IHtcblxuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5feDtcblxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdHRoaXMuX3ggPSB2YWx1ZTtcblx0XHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0eToge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLl95O1xuXG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0dGhpcy5feSA9IHZhbHVlO1xuXHRcdFx0dGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHR9XG5cblx0fSxcblxuXHR6OiB7XG5cblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuX3o7XG5cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHR0aGlzLl96ID0gdmFsdWU7XG5cdFx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdG9yZGVyOiB7XG5cblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuX29yZGVyO1xuXG5cdFx0fSxcblxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0dGhpcy5fb3JkZXIgPSB2YWx1ZTtcblx0XHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG5PYmplY3QuYXNzaWduKCBFdWxlci5wcm90b3R5cGUsIHtcblxuXHRpc0V1bGVyOiB0cnVlLFxuXG5cdHNldDogZnVuY3Rpb24gKCB4LCB5LCB6LCBvcmRlciApIHtcblxuXHRcdHRoaXMuX3ggPSB4O1xuXHRcdHRoaXMuX3kgPSB5O1xuXHRcdHRoaXMuX3ogPSB6O1xuXHRcdHRoaXMuX29yZGVyID0gb3JkZXIgfHwgdGhpcy5fb3JkZXI7XG5cblx0XHR0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvciggdGhpcy5feCwgdGhpcy5feSwgdGhpcy5feiwgdGhpcy5fb3JkZXIgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggZXVsZXIgKSB7XG5cblx0XHR0aGlzLl94ID0gZXVsZXIuX3g7XG5cdFx0dGhpcy5feSA9IGV1bGVyLl95O1xuXHRcdHRoaXMuX3ogPSBldWxlci5fejtcblx0XHR0aGlzLl9vcmRlciA9IGV1bGVyLl9vcmRlcjtcblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRGcm9tUm90YXRpb25NYXRyaXg6IGZ1bmN0aW9uICggbSwgb3JkZXIsIHVwZGF0ZSApIHtcblxuXHRcdHZhciBjbGFtcCA9IF9NYXRoLmNsYW1wO1xuXG5cdFx0Ly8gYXNzdW1lcyB0aGUgdXBwZXIgM3gzIG9mIG0gaXMgYSBwdXJlIHJvdGF0aW9uIG1hdHJpeCAoaS5lLCB1bnNjYWxlZClcblxuXHRcdHZhciB0ZSA9IG0uZWxlbWVudHM7XG5cdFx0dmFyIG0xMSA9IHRlWyAwIF0sIG0xMiA9IHRlWyA0IF0sIG0xMyA9IHRlWyA4IF07XG5cdFx0dmFyIG0yMSA9IHRlWyAxIF0sIG0yMiA9IHRlWyA1IF0sIG0yMyA9IHRlWyA5IF07XG5cdFx0dmFyIG0zMSA9IHRlWyAyIF0sIG0zMiA9IHRlWyA2IF0sIG0zMyA9IHRlWyAxMCBdO1xuXG5cdFx0b3JkZXIgPSBvcmRlciB8fCB0aGlzLl9vcmRlcjtcblxuXHRcdGlmICggb3JkZXIgPT09ICdYWVonICkge1xuXG5cdFx0XHR0aGlzLl95ID0gTWF0aC5hc2luKCBjbGFtcCggbTEzLCAtIDEsIDEgKSApO1xuXG5cdFx0XHRpZiAoIE1hdGguYWJzKCBtMTMgKSA8IDAuOTk5OTkgKSB7XG5cblx0XHRcdFx0dGhpcy5feCA9IE1hdGguYXRhbjIoIC0gbTIzLCBtMzMgKTtcblx0XHRcdFx0dGhpcy5feiA9IE1hdGguYXRhbjIoIC0gbTEyLCBtMTEgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHR0aGlzLl94ID0gTWF0aC5hdGFuMiggbTMyLCBtMjIgKTtcblx0XHRcdFx0dGhpcy5feiA9IDA7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSBpZiAoIG9yZGVyID09PSAnWVhaJyApIHtcblxuXHRcdFx0dGhpcy5feCA9IE1hdGguYXNpbiggLSBjbGFtcCggbTIzLCAtIDEsIDEgKSApO1xuXG5cdFx0XHRpZiAoIE1hdGguYWJzKCBtMjMgKSA8IDAuOTk5OTkgKSB7XG5cblx0XHRcdFx0dGhpcy5feSA9IE1hdGguYXRhbjIoIG0xMywgbTMzICk7XG5cdFx0XHRcdHRoaXMuX3ogPSBNYXRoLmF0YW4yKCBtMjEsIG0yMiApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHRoaXMuX3kgPSBNYXRoLmF0YW4yKCAtIG0zMSwgbTExICk7XG5cdFx0XHRcdHRoaXMuX3ogPSAwO1xuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBvcmRlciA9PT0gJ1pYWScgKSB7XG5cblx0XHRcdHRoaXMuX3ggPSBNYXRoLmFzaW4oIGNsYW1wKCBtMzIsIC0gMSwgMSApICk7XG5cblx0XHRcdGlmICggTWF0aC5hYnMoIG0zMiApIDwgMC45OTk5OSApIHtcblxuXHRcdFx0XHR0aGlzLl95ID0gTWF0aC5hdGFuMiggLSBtMzEsIG0zMyApO1xuXHRcdFx0XHR0aGlzLl96ID0gTWF0aC5hdGFuMiggLSBtMTIsIG0yMiApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHRoaXMuX3kgPSAwO1xuXHRcdFx0XHR0aGlzLl96ID0gTWF0aC5hdGFuMiggbTIxLCBtMTEgKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggb3JkZXIgPT09ICdaWVgnICkge1xuXG5cdFx0XHR0aGlzLl95ID0gTWF0aC5hc2luKCAtIGNsYW1wKCBtMzEsIC0gMSwgMSApICk7XG5cblx0XHRcdGlmICggTWF0aC5hYnMoIG0zMSApIDwgMC45OTk5OSApIHtcblxuXHRcdFx0XHR0aGlzLl94ID0gTWF0aC5hdGFuMiggbTMyLCBtMzMgKTtcblx0XHRcdFx0dGhpcy5feiA9IE1hdGguYXRhbjIoIG0yMSwgbTExICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dGhpcy5feCA9IDA7XG5cdFx0XHRcdHRoaXMuX3ogPSBNYXRoLmF0YW4yKCAtIG0xMiwgbTIyICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSBpZiAoIG9yZGVyID09PSAnWVpYJyApIHtcblxuXHRcdFx0dGhpcy5feiA9IE1hdGguYXNpbiggY2xhbXAoIG0yMSwgLSAxLCAxICkgKTtcblxuXHRcdFx0aWYgKCBNYXRoLmFicyggbTIxICkgPCAwLjk5OTk5ICkge1xuXG5cdFx0XHRcdHRoaXMuX3ggPSBNYXRoLmF0YW4yKCAtIG0yMywgbTIyICk7XG5cdFx0XHRcdHRoaXMuX3kgPSBNYXRoLmF0YW4yKCAtIG0zMSwgbTExICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dGhpcy5feCA9IDA7XG5cdFx0XHRcdHRoaXMuX3kgPSBNYXRoLmF0YW4yKCBtMTMsIG0zMyApO1xuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBvcmRlciA9PT0gJ1haWScgKSB7XG5cblx0XHRcdHRoaXMuX3ogPSBNYXRoLmFzaW4oIC0gY2xhbXAoIG0xMiwgLSAxLCAxICkgKTtcblxuXHRcdFx0aWYgKCBNYXRoLmFicyggbTEyICkgPCAwLjk5OTk5ICkge1xuXG5cdFx0XHRcdHRoaXMuX3ggPSBNYXRoLmF0YW4yKCBtMzIsIG0yMiApO1xuXHRcdFx0XHR0aGlzLl95ID0gTWF0aC5hdGFuMiggbTEzLCBtMTEgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHR0aGlzLl94ID0gTWF0aC5hdGFuMiggLSBtMjMsIG0zMyApO1xuXHRcdFx0XHR0aGlzLl95ID0gMDtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuRXVsZXI6IC5zZXRGcm9tUm90YXRpb25NYXRyaXgoKSBnaXZlbiB1bnN1cHBvcnRlZCBvcmRlcjogJyArIG9yZGVyICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLl9vcmRlciA9IG9yZGVyO1xuXG5cdFx0aWYgKCB1cGRhdGUgIT09IGZhbHNlICkgdGhpcy5vbkNoYW5nZUNhbGxiYWNrKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21RdWF0ZXJuaW9uOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBzZXRGcm9tUXVhdGVybmlvbiggcSwgb3JkZXIsIHVwZGF0ZSApIHtcblxuXHRcdFx0bWF0cml4Lm1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKCBxICk7XG5cblx0XHRcdHJldHVybiB0aGlzLnNldEZyb21Sb3RhdGlvbk1hdHJpeCggbWF0cml4LCBvcmRlciwgdXBkYXRlICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRzZXRGcm9tVmVjdG9yMzogZnVuY3Rpb24gKCB2LCBvcmRlciApIHtcblxuXHRcdHJldHVybiB0aGlzLnNldCggdi54LCB2LnksIHYueiwgb3JkZXIgfHwgdGhpcy5fb3JkZXIgKTtcblxuXHR9LFxuXG5cdHJlb3JkZXI6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIFdBUk5JTkc6IHRoaXMgZGlzY2FyZHMgcmV2b2x1dGlvbiBpbmZvcm1hdGlvbiAtYmhvdXN0b25cblxuXHRcdHZhciBxID0gbmV3IFF1YXRlcm5pb24oKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiByZW9yZGVyKCBuZXdPcmRlciApIHtcblxuXHRcdFx0cS5zZXRGcm9tRXVsZXIoIHRoaXMgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXMuc2V0RnJvbVF1YXRlcm5pb24oIHEsIG5ld09yZGVyICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRlcXVhbHM6IGZ1bmN0aW9uICggZXVsZXIgKSB7XG5cblx0XHRyZXR1cm4gKCBldWxlci5feCA9PT0gdGhpcy5feCApICYmICggZXVsZXIuX3kgPT09IHRoaXMuX3kgKSAmJiAoIGV1bGVyLl96ID09PSB0aGlzLl96ICkgJiYgKCBldWxlci5fb3JkZXIgPT09IHRoaXMuX29yZGVyICk7XG5cblx0fSxcblxuXHRmcm9tQXJyYXk6IGZ1bmN0aW9uICggYXJyYXkgKSB7XG5cblx0XHR0aGlzLl94ID0gYXJyYXlbIDAgXTtcblx0XHR0aGlzLl95ID0gYXJyYXlbIDEgXTtcblx0XHR0aGlzLl96ID0gYXJyYXlbIDIgXTtcblx0XHRpZiAoIGFycmF5WyAzIF0gIT09IHVuZGVmaW5lZCApIHRoaXMuX29yZGVyID0gYXJyYXlbIDMgXTtcblxuXHRcdHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR0b0FycmF5OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIGFycmF5ID09PSB1bmRlZmluZWQgKSBhcnJheSA9IFtdO1xuXHRcdGlmICggb2Zmc2V0ID09PSB1bmRlZmluZWQgKSBvZmZzZXQgPSAwO1xuXG5cdFx0YXJyYXlbIG9mZnNldCBdID0gdGhpcy5feDtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMSBdID0gdGhpcy5feTtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMiBdID0gdGhpcy5fejtcblx0XHRhcnJheVsgb2Zmc2V0ICsgMyBdID0gdGhpcy5fb3JkZXI7XG5cblx0XHRyZXR1cm4gYXJyYXk7XG5cblx0fSxcblxuXHR0b1ZlY3RvcjM6IGZ1bmN0aW9uICggb3B0aW9uYWxSZXN1bHQgKSB7XG5cblx0XHRpZiAoIG9wdGlvbmFsUmVzdWx0ICkge1xuXG5cdFx0XHRyZXR1cm4gb3B0aW9uYWxSZXN1bHQuc2V0KCB0aGlzLl94LCB0aGlzLl95LCB0aGlzLl96ICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRyZXR1cm4gbmV3IFZlY3RvcjMoIHRoaXMuX3gsIHRoaXMuX3ksIHRoaXMuX3ogKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdG9uQ2hhbmdlOiBmdW5jdGlvbiAoIGNhbGxiYWNrICkge1xuXG5cdFx0dGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gY2FsbGJhY2s7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG9uQ2hhbmdlQ2FsbGJhY2s6IGZ1bmN0aW9uICgpIHt9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIExheWVycygpIHtcblxuXHR0aGlzLm1hc2sgPSAxIHwgMDtcblxufVxuXG5PYmplY3QuYXNzaWduKCBMYXllcnMucHJvdG90eXBlLCB7XG5cblx0c2V0OiBmdW5jdGlvbiAoIGNoYW5uZWwgKSB7XG5cblx0XHR0aGlzLm1hc2sgPSAxIDw8IGNoYW5uZWwgfCAwO1xuXG5cdH0sXG5cblx0ZW5hYmxlOiBmdW5jdGlvbiAoIGNoYW5uZWwgKSB7XG5cblx0XHR0aGlzLm1hc2sgfD0gMSA8PCBjaGFubmVsIHwgMDtcblxuXHR9LFxuXG5cdHRvZ2dsZTogZnVuY3Rpb24gKCBjaGFubmVsICkge1xuXG5cdFx0dGhpcy5tYXNrIF49IDEgPDwgY2hhbm5lbCB8IDA7XG5cblx0fSxcblxuXHRkaXNhYmxlOiBmdW5jdGlvbiAoIGNoYW5uZWwgKSB7XG5cblx0XHR0aGlzLm1hc2sgJj0gfiAoIDEgPDwgY2hhbm5lbCB8IDAgKTtcblxuXHR9LFxuXG5cdHRlc3Q6IGZ1bmN0aW9uICggbGF5ZXJzICkge1xuXG5cdFx0cmV0dXJuICggdGhpcy5tYXNrICYgbGF5ZXJzLm1hc2sgKSAhPT0gMDtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIFdlc3RMYW5nbGV5IC8gaHR0cDovL2dpdGh1Yi5jb20vV2VzdExhbmdsZXlcbiAqIEBhdXRob3IgZWxlcGhhbnRhdHdvcmsgLyB3d3cuZWxlcGhhbnRhdHdvcmsuY2hcbiAqL1xuXG52YXIgb2JqZWN0M0RJZCA9IDA7XG5cbmZ1bmN0aW9uIE9iamVjdDNEKCkge1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggdGhpcywgJ2lkJywgeyB2YWx1ZTogb2JqZWN0M0RJZCArKyB9ICk7XG5cblx0dGhpcy51dWlkID0gX01hdGguZ2VuZXJhdGVVVUlEKCk7XG5cblx0dGhpcy5uYW1lID0gJyc7XG5cdHRoaXMudHlwZSA9ICdPYmplY3QzRCc7XG5cblx0dGhpcy5wYXJlbnQgPSBudWxsO1xuXHR0aGlzLmNoaWxkcmVuID0gW107XG5cblx0dGhpcy51cCA9IE9iamVjdDNELkRlZmF1bHRVcC5jbG9uZSgpO1xuXG5cdHZhciBwb3NpdGlvbiA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciByb3RhdGlvbiA9IG5ldyBFdWxlcigpO1xuXHR2YXIgcXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cdHZhciBzY2FsZSA9IG5ldyBWZWN0b3IzKCAxLCAxLCAxICk7XG5cblx0ZnVuY3Rpb24gb25Sb3RhdGlvbkNoYW5nZSgpIHtcblxuXHRcdHF1YXRlcm5pb24uc2V0RnJvbUV1bGVyKCByb3RhdGlvbiwgZmFsc2UgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gb25RdWF0ZXJuaW9uQ2hhbmdlKCkge1xuXG5cdFx0cm90YXRpb24uc2V0RnJvbVF1YXRlcm5pb24oIHF1YXRlcm5pb24sIHVuZGVmaW5lZCwgZmFsc2UgKTtcblxuXHR9XG5cblx0cm90YXRpb24ub25DaGFuZ2UoIG9uUm90YXRpb25DaGFuZ2UgKTtcblx0cXVhdGVybmlvbi5vbkNoYW5nZSggb25RdWF0ZXJuaW9uQ2hhbmdlICk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIHRoaXMsIHtcblx0XHRwb3NpdGlvbjoge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdHZhbHVlOiBwb3NpdGlvblxuXHRcdH0sXG5cdFx0cm90YXRpb246IHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHR2YWx1ZTogcm90YXRpb25cblx0XHR9LFxuXHRcdHF1YXRlcm5pb246IHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHR2YWx1ZTogcXVhdGVybmlvblxuXHRcdH0sXG5cdFx0c2NhbGU6IHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHR2YWx1ZTogc2NhbGVcblx0XHR9LFxuXHRcdG1vZGVsVmlld01hdHJpeDoge1xuXHRcdFx0dmFsdWU6IG5ldyBNYXRyaXg0KClcblx0XHR9LFxuXHRcdG5vcm1hbE1hdHJpeDoge1xuXHRcdFx0dmFsdWU6IG5ldyBNYXRyaXgzKClcblx0XHR9XG5cdH0gKTtcblxuXHR0aGlzLm1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdHRoaXMubWF0cml4V29ybGQgPSBuZXcgTWF0cml4NCgpO1xuXG5cdHRoaXMubWF0cml4QXV0b1VwZGF0ZSA9IE9iamVjdDNELkRlZmF1bHRNYXRyaXhBdXRvVXBkYXRlO1xuXHR0aGlzLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLmxheWVycyA9IG5ldyBMYXllcnMoKTtcblx0dGhpcy52aXNpYmxlID0gdHJ1ZTtcblxuXHR0aGlzLmNhc3RTaGFkb3cgPSBmYWxzZTtcblx0dGhpcy5yZWNlaXZlU2hhZG93ID0gZmFsc2U7XG5cblx0dGhpcy5mcnVzdHVtQ3VsbGVkID0gdHJ1ZTtcblx0dGhpcy5yZW5kZXJPcmRlciA9IDA7XG5cblx0dGhpcy51c2VyRGF0YSA9IHt9O1xuXG5cdHRoaXMub25CZWZvcmVSZW5kZXIgPSBmdW5jdGlvbiAoKSB7fTtcblx0dGhpcy5vbkFmdGVyUmVuZGVyID0gZnVuY3Rpb24gKCkge307XG5cbn1cblxuT2JqZWN0M0QuRGVmYXVsdFVwID0gbmV3IFZlY3RvcjMoIDAsIDEsIDAgKTtcbk9iamVjdDNELkRlZmF1bHRNYXRyaXhBdXRvVXBkYXRlID0gdHJ1ZTtcblxuT2JqZWN0LmFzc2lnbiggT2JqZWN0M0QucHJvdG90eXBlLCBFdmVudERpc3BhdGNoZXIucHJvdG90eXBlLCB7XG5cblx0aXNPYmplY3QzRDogdHJ1ZSxcblxuXHRhcHBseU1hdHJpeDogZnVuY3Rpb24gKCBtYXRyaXggKSB7XG5cblx0XHR0aGlzLm1hdHJpeC5tdWx0aXBseU1hdHJpY2VzKCBtYXRyaXgsIHRoaXMubWF0cml4ICk7XG5cblx0XHR0aGlzLm1hdHJpeC5kZWNvbXBvc2UoIHRoaXMucG9zaXRpb24sIHRoaXMucXVhdGVybmlvbiwgdGhpcy5zY2FsZSApO1xuXG5cdH0sXG5cblx0c2V0Um90YXRpb25Gcm9tQXhpc0FuZ2xlOiBmdW5jdGlvbiAoIGF4aXMsIGFuZ2xlICkge1xuXG5cdFx0Ly8gYXNzdW1lcyBheGlzIGlzIG5vcm1hbGl6ZWRcblxuXHRcdHRoaXMucXVhdGVybmlvbi5zZXRGcm9tQXhpc0FuZ2xlKCBheGlzLCBhbmdsZSApO1xuXG5cdH0sXG5cblx0c2V0Um90YXRpb25Gcm9tRXVsZXI6IGZ1bmN0aW9uICggZXVsZXIgKSB7XG5cblx0XHR0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUV1bGVyKCBldWxlciwgdHJ1ZSApO1xuXG5cdH0sXG5cblx0c2V0Um90YXRpb25Gcm9tTWF0cml4OiBmdW5jdGlvbiAoIG0gKSB7XG5cblx0XHQvLyBhc3N1bWVzIHRoZSB1cHBlciAzeDMgb2YgbSBpcyBhIHB1cmUgcm90YXRpb24gbWF0cml4IChpLmUsIHVuc2NhbGVkKVxuXG5cdFx0dGhpcy5xdWF0ZXJuaW9uLnNldEZyb21Sb3RhdGlvbk1hdHJpeCggbSApO1xuXG5cdH0sXG5cblx0c2V0Um90YXRpb25Gcm9tUXVhdGVybmlvbjogZnVuY3Rpb24gKCBxICkge1xuXG5cdFx0Ly8gYXNzdW1lcyBxIGlzIG5vcm1hbGl6ZWRcblxuXHRcdHRoaXMucXVhdGVybmlvbi5jb3B5KCBxICk7XG5cblx0fSxcblxuXHRyb3RhdGVPbkF4aXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIHJvdGF0ZSBvYmplY3Qgb24gYXhpcyBpbiBvYmplY3Qgc3BhY2Vcblx0XHQvLyBheGlzIGlzIGFzc3VtZWQgdG8gYmUgbm9ybWFsaXplZFxuXG5cdFx0dmFyIHExID0gbmV3IFF1YXRlcm5pb24oKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiByb3RhdGVPbkF4aXMoIGF4aXMsIGFuZ2xlICkge1xuXG5cdFx0XHRxMS5zZXRGcm9tQXhpc0FuZ2xlKCBheGlzLCBhbmdsZSApO1xuXG5cdFx0XHR0aGlzLnF1YXRlcm5pb24ubXVsdGlwbHkoIHExICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0cm90YXRlWDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoIDEsIDAsIDAgKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiByb3RhdGVYKCBhbmdsZSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKCB2MSwgYW5nbGUgKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdHJvdGF0ZVk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCAwLCAxLCAwICk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWSggYW5nbGUgKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLnJvdGF0ZU9uQXhpcyggdjEsIGFuZ2xlICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRyb3RhdGVaOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMyggMCwgMCwgMSApO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHJvdGF0ZVooIGFuZ2xlICkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoIHYxLCBhbmdsZSApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlT25BeGlzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyB0cmFuc2xhdGUgb2JqZWN0IGJ5IGRpc3RhbmNlIGFsb25nIGF4aXMgaW4gb2JqZWN0IHNwYWNlXG5cdFx0Ly8gYXhpcyBpcyBhc3N1bWVkIHRvIGJlIG5vcm1hbGl6ZWRcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdHJhbnNsYXRlT25BeGlzKCBheGlzLCBkaXN0YW5jZSApIHtcblxuXHRcdFx0djEuY29weSggYXhpcyApLmFwcGx5UXVhdGVybmlvbiggdGhpcy5xdWF0ZXJuaW9uICk7XG5cblx0XHRcdHRoaXMucG9zaXRpb24uYWRkKCB2MS5tdWx0aXBseVNjYWxhciggZGlzdGFuY2UgKSApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdHRyYW5zbGF0ZVg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCAxLCAwLCAwICk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdHJhbnNsYXRlWCggZGlzdGFuY2UgKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLnRyYW5zbGF0ZU9uQXhpcyggdjEsIGRpc3RhbmNlICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHR0cmFuc2xhdGVZOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMyggMCwgMSwgMCApO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHRyYW5zbGF0ZVkoIGRpc3RhbmNlICkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoIHYxLCBkaXN0YW5jZSApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlWjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHYxID0gbmV3IFZlY3RvcjMoIDAsIDAsIDEgKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiB0cmFuc2xhdGVaKCBkaXN0YW5jZSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMudHJhbnNsYXRlT25BeGlzKCB2MSwgZGlzdGFuY2UgKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGxvY2FsVG9Xb3JsZDogZnVuY3Rpb24gKCB2ZWN0b3IgKSB7XG5cblx0XHRyZXR1cm4gdmVjdG9yLmFwcGx5TWF0cml4NCggdGhpcy5tYXRyaXhXb3JsZCApO1xuXG5cdH0sXG5cblx0d29ybGRUb0xvY2FsOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbTEgPSBuZXcgTWF0cml4NCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHdvcmxkVG9Mb2NhbCggdmVjdG9yICkge1xuXG5cdFx0XHRyZXR1cm4gdmVjdG9yLmFwcGx5TWF0cml4NCggbTEuZ2V0SW52ZXJzZSggdGhpcy5tYXRyaXhXb3JsZCApICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRsb29rQXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdC8vIFRoaXMgcm91dGluZSBkb2VzIG5vdCBzdXBwb3J0IG9iamVjdHMgd2l0aCByb3RhdGVkIGFuZC9vciB0cmFuc2xhdGVkIHBhcmVudChzKVxuXG5cdFx0dmFyIG0xID0gbmV3IE1hdHJpeDQoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBsb29rQXQoIHZlY3RvciApIHtcblxuXHRcdFx0aWYgKCB0aGlzLmlzQ2FtZXJhICkge1xuXG5cdFx0XHRcdG0xLmxvb2tBdCggdGhpcy5wb3NpdGlvbiwgdmVjdG9yLCB0aGlzLnVwICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0bTEubG9va0F0KCB2ZWN0b3IsIHRoaXMucG9zaXRpb24sIHRoaXMudXAgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KCBtMSApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0YWRkOiBmdW5jdGlvbiAoIG9iamVjdCApIHtcblxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA+IDEgKSB7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0dGhpcy5hZGQoIGFyZ3VtZW50c1sgaSBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9XG5cblx0XHRpZiAoIG9iamVjdCA9PT0gdGhpcyApIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggXCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBjYW4ndCBiZSBhZGRlZCBhcyBhIGNoaWxkIG9mIGl0c2VsZi5cIiwgb2JqZWN0ICk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH1cblxuXHRcdGlmICggKCBvYmplY3QgJiYgb2JqZWN0LmlzT2JqZWN0M0QgKSApIHtcblxuXHRcdFx0aWYgKCBvYmplY3QucGFyZW50ICE9PSBudWxsICkge1xuXG5cdFx0XHRcdG9iamVjdC5wYXJlbnQucmVtb3ZlKCBvYmplY3QgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRvYmplY3QucGFyZW50ID0gdGhpcztcblx0XHRcdG9iamVjdC5kaXNwYXRjaEV2ZW50KCB7IHR5cGU6ICdhZGRlZCcgfSApO1xuXG5cdFx0XHR0aGlzLmNoaWxkcmVuLnB1c2goIG9iamVjdCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggXCJUSFJFRS5PYmplY3QzRC5hZGQ6IG9iamVjdCBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuT2JqZWN0M0QuXCIsIG9iamVjdCApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uICggb2JqZWN0ICkge1xuXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoID4gMSApIHtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHR0aGlzLnJlbW92ZSggYXJndW1lbnRzWyBpIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIGluZGV4ID0gdGhpcy5jaGlsZHJlbi5pbmRleE9mKCBvYmplY3QgKTtcblxuXHRcdGlmICggaW5kZXggIT09IC0gMSApIHtcblxuXHRcdFx0b2JqZWN0LnBhcmVudCA9IG51bGw7XG5cblx0XHRcdG9iamVjdC5kaXNwYXRjaEV2ZW50KCB7IHR5cGU6ICdyZW1vdmVkJyB9ICk7XG5cblx0XHRcdHRoaXMuY2hpbGRyZW4uc3BsaWNlKCBpbmRleCwgMSApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Z2V0T2JqZWN0QnlJZDogZnVuY3Rpb24gKCBpZCApIHtcblxuXHRcdHJldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoICdpZCcsIGlkICk7XG5cblx0fSxcblxuXHRnZXRPYmplY3RCeU5hbWU6IGZ1bmN0aW9uICggbmFtZSApIHtcblxuXHRcdHJldHVybiB0aGlzLmdldE9iamVjdEJ5UHJvcGVydHkoICduYW1lJywgbmFtZSApO1xuXG5cdH0sXG5cblx0Z2V0T2JqZWN0QnlQcm9wZXJ0eTogZnVuY3Rpb24gKCBuYW1lLCB2YWx1ZSApIHtcblxuXHRcdGlmICggdGhpc1sgbmFtZSBdID09PSB2YWx1ZSApIHJldHVybiB0aGlzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuWyBpIF07XG5cdFx0XHR2YXIgb2JqZWN0ID0gY2hpbGQuZ2V0T2JqZWN0QnlQcm9wZXJ0eSggbmFtZSwgdmFsdWUgKTtcblxuXHRcdFx0aWYgKCBvYmplY3QgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gb2JqZWN0O1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXG5cdH0sXG5cblx0Z2V0V29ybGRQb3NpdGlvbjogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXG5cdFx0dGhpcy51cGRhdGVNYXRyaXhXb3JsZCggdHJ1ZSApO1xuXG5cdFx0cmV0dXJuIHJlc3VsdC5zZXRGcm9tTWF0cml4UG9zaXRpb24oIHRoaXMubWF0cml4V29ybGQgKTtcblxuXHR9LFxuXG5cdGdldFdvcmxkUXVhdGVybmlvbjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHBvc2l0aW9uID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgc2NhbGUgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGdldFdvcmxkUXVhdGVybmlvbiggb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgUXVhdGVybmlvbigpO1xuXG5cdFx0XHR0aGlzLnVwZGF0ZU1hdHJpeFdvcmxkKCB0cnVlICk7XG5cblx0XHRcdHRoaXMubWF0cml4V29ybGQuZGVjb21wb3NlKCBwb3NpdGlvbiwgcmVzdWx0LCBzY2FsZSApO1xuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Z2V0V29ybGRSb3RhdGlvbjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGdldFdvcmxkUm90YXRpb24oIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IEV1bGVyKCk7XG5cblx0XHRcdHRoaXMuZ2V0V29ybGRRdWF0ZXJuaW9uKCBxdWF0ZXJuaW9uICk7XG5cblx0XHRcdHJldHVybiByZXN1bHQuc2V0RnJvbVF1YXRlcm5pb24oIHF1YXRlcm5pb24sIHRoaXMucm90YXRpb24ub3JkZXIsIGZhbHNlICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRnZXRXb3JsZFNjYWxlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcG9zaXRpb24gPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBxdWF0ZXJuaW9uID0gbmV3IFF1YXRlcm5pb24oKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBnZXRXb3JsZFNjYWxlKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRcdHRoaXMudXBkYXRlTWF0cml4V29ybGQoIHRydWUgKTtcblxuXHRcdFx0dGhpcy5tYXRyaXhXb3JsZC5kZWNvbXBvc2UoIHBvc2l0aW9uLCBxdWF0ZXJuaW9uLCByZXN1bHQgKTtcblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGdldFdvcmxkRGlyZWN0aW9uOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZ2V0V29ybGREaXJlY3Rpb24oIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0dGhpcy5nZXRXb3JsZFF1YXRlcm5pb24oIHF1YXRlcm5pb24gKTtcblxuXHRcdFx0cmV0dXJuIHJlc3VsdC5zZXQoIDAsIDAsIDEgKS5hcHBseVF1YXRlcm5pb24oIHF1YXRlcm5pb24gKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdHJheWNhc3Q6IGZ1bmN0aW9uICgpIHt9LFxuXG5cdHRyYXZlcnNlOiBmdW5jdGlvbiAoIGNhbGxiYWNrICkge1xuXG5cdFx0Y2FsbGJhY2soIHRoaXMgKTtcblxuXHRcdHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRjaGlsZHJlblsgaSBdLnRyYXZlcnNlKCBjYWxsYmFjayApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0dHJhdmVyc2VWaXNpYmxlOiBmdW5jdGlvbiAoIGNhbGxiYWNrICkge1xuXG5cdFx0aWYgKCB0aGlzLnZpc2libGUgPT09IGZhbHNlICkgcmV0dXJuO1xuXG5cdFx0Y2FsbGJhY2soIHRoaXMgKTtcblxuXHRcdHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRjaGlsZHJlblsgaSBdLnRyYXZlcnNlVmlzaWJsZSggY2FsbGJhY2sgKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdHRyYXZlcnNlQW5jZXN0b3JzOiBmdW5jdGlvbiAoIGNhbGxiYWNrICkge1xuXG5cdFx0dmFyIHBhcmVudCA9IHRoaXMucGFyZW50O1xuXG5cdFx0aWYgKCBwYXJlbnQgIT09IG51bGwgKSB7XG5cblx0XHRcdGNhbGxiYWNrKCBwYXJlbnQgKTtcblxuXHRcdFx0cGFyZW50LnRyYXZlcnNlQW5jZXN0b3JzKCBjYWxsYmFjayApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0dXBkYXRlTWF0cml4OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLm1hdHJpeC5jb21wb3NlKCB0aGlzLnBvc2l0aW9uLCB0aGlzLnF1YXRlcm5pb24sIHRoaXMuc2NhbGUgKTtcblxuXHRcdHRoaXMubWF0cml4V29ybGROZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0fSxcblxuXHR1cGRhdGVNYXRyaXhXb3JsZDogZnVuY3Rpb24gKCBmb3JjZSApIHtcblxuXHRcdGlmICggdGhpcy5tYXRyaXhBdXRvVXBkYXRlICkgdGhpcy51cGRhdGVNYXRyaXgoKTtcblxuXHRcdGlmICggdGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlIHx8IGZvcmNlICkge1xuXG5cdFx0XHRpZiAoIHRoaXMucGFyZW50ID09PSBudWxsICkge1xuXG5cdFx0XHRcdHRoaXMubWF0cml4V29ybGQuY29weSggdGhpcy5tYXRyaXggKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHR0aGlzLm1hdHJpeFdvcmxkLm11bHRpcGx5TWF0cmljZXMoIHRoaXMucGFyZW50Lm1hdHJpeFdvcmxkLCB0aGlzLm1hdHJpeCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubWF0cml4V29ybGROZWVkc1VwZGF0ZSA9IGZhbHNlO1xuXG5cdFx0XHRmb3JjZSA9IHRydWU7XG5cblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgY2hpbGRyZW5cblxuXHRcdHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRjaGlsZHJlblsgaSBdLnVwZGF0ZU1hdHJpeFdvcmxkKCBmb3JjZSApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0dG9KU09OOiBmdW5jdGlvbiAoIG1ldGEgKSB7XG5cblx0XHQvLyBtZXRhIGlzICcnIHdoZW4gY2FsbGVkIGZyb20gSlNPTi5zdHJpbmdpZnlcblx0XHR2YXIgaXNSb290T2JqZWN0ID0gKCBtZXRhID09PSB1bmRlZmluZWQgfHwgbWV0YSA9PT0gJycgKTtcblxuXHRcdHZhciBvdXRwdXQgPSB7fTtcblxuXHRcdC8vIG1ldGEgaXMgYSBoYXNoIHVzZWQgdG8gY29sbGVjdCBnZW9tZXRyaWVzLCBtYXRlcmlhbHMuXG5cdFx0Ly8gbm90IHByb3ZpZGluZyBpdCBpbXBsaWVzIHRoYXQgdGhpcyBpcyB0aGUgcm9vdCBvYmplY3Rcblx0XHQvLyBiZWluZyBzZXJpYWxpemVkLlxuXHRcdGlmICggaXNSb290T2JqZWN0ICkge1xuXG5cdFx0XHQvLyBpbml0aWFsaXplIG1ldGEgb2JqXG5cdFx0XHRtZXRhID0ge1xuXHRcdFx0XHRnZW9tZXRyaWVzOiB7fSxcblx0XHRcdFx0bWF0ZXJpYWxzOiB7fSxcblx0XHRcdFx0dGV4dHVyZXM6IHt9LFxuXHRcdFx0XHRpbWFnZXM6IHt9XG5cdFx0XHR9O1xuXG5cdFx0XHRvdXRwdXQubWV0YWRhdGEgPSB7XG5cdFx0XHRcdHZlcnNpb246IDQuNSxcblx0XHRcdFx0dHlwZTogJ09iamVjdCcsXG5cdFx0XHRcdGdlbmVyYXRvcjogJ09iamVjdDNELnRvSlNPTidcblx0XHRcdH07XG5cblx0XHR9XG5cblx0XHQvLyBzdGFuZGFyZCBPYmplY3QzRCBzZXJpYWxpemF0aW9uXG5cblx0XHR2YXIgb2JqZWN0ID0ge307XG5cblx0XHRvYmplY3QudXVpZCA9IHRoaXMudXVpZDtcblx0XHRvYmplY3QudHlwZSA9IHRoaXMudHlwZTtcblxuXHRcdGlmICggdGhpcy5uYW1lICE9PSAnJyApIG9iamVjdC5uYW1lID0gdGhpcy5uYW1lO1xuXHRcdGlmICggSlNPTi5zdHJpbmdpZnkoIHRoaXMudXNlckRhdGEgKSAhPT0gJ3t9JyApIG9iamVjdC51c2VyRGF0YSA9IHRoaXMudXNlckRhdGE7XG5cdFx0aWYgKCB0aGlzLmNhc3RTaGFkb3cgPT09IHRydWUgKSBvYmplY3QuY2FzdFNoYWRvdyA9IHRydWU7XG5cdFx0aWYgKCB0aGlzLnJlY2VpdmVTaGFkb3cgPT09IHRydWUgKSBvYmplY3QucmVjZWl2ZVNoYWRvdyA9IHRydWU7XG5cdFx0aWYgKCB0aGlzLnZpc2libGUgPT09IGZhbHNlICkgb2JqZWN0LnZpc2libGUgPSBmYWxzZTtcblxuXHRcdG9iamVjdC5tYXRyaXggPSB0aGlzLm1hdHJpeC50b0FycmF5KCk7XG5cblx0XHQvL1xuXG5cdFx0ZnVuY3Rpb24gc2VyaWFsaXplKCBsaWJyYXJ5LCBlbGVtZW50ICkge1xuXG5cdFx0XHRpZiAoIGxpYnJhcnlbIGVsZW1lbnQudXVpZCBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0bGlicmFyeVsgZWxlbWVudC51dWlkIF0gPSBlbGVtZW50LnRvSlNPTiggbWV0YSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtZW50LnV1aWQ7XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuZ2VvbWV0cnkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0b2JqZWN0Lmdlb21ldHJ5ID0gc2VyaWFsaXplKCBtZXRhLmdlb21ldHJpZXMsIHRoaXMuZ2VvbWV0cnkgKTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5tYXRlcmlhbCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHRoaXMubWF0ZXJpYWwgKSApIHtcblxuXHRcdFx0XHR2YXIgdXVpZHMgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSB0aGlzLm1hdGVyaWFsLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHR1dWlkcy5wdXNoKCBzZXJpYWxpemUoIG1ldGEubWF0ZXJpYWxzLCB0aGlzLm1hdGVyaWFsWyBpIF0gKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRvYmplY3QubWF0ZXJpYWwgPSB1dWlkcztcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRvYmplY3QubWF0ZXJpYWwgPSBzZXJpYWxpemUoIG1ldGEubWF0ZXJpYWxzLCB0aGlzLm1hdGVyaWFsICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdC8vXG5cblx0XHRpZiAoIHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0b2JqZWN0LmNoaWxkcmVuID0gW107XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdG9iamVjdC5jaGlsZHJlbi5wdXNoKCB0aGlzLmNoaWxkcmVuWyBpIF0udG9KU09OKCBtZXRhICkub2JqZWN0ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggaXNSb290T2JqZWN0ICkge1xuXG5cdFx0XHR2YXIgZ2VvbWV0cmllcyA9IGV4dHJhY3RGcm9tQ2FjaGUoIG1ldGEuZ2VvbWV0cmllcyApO1xuXHRcdFx0dmFyIG1hdGVyaWFscyA9IGV4dHJhY3RGcm9tQ2FjaGUoIG1ldGEubWF0ZXJpYWxzICk7XG5cdFx0XHR2YXIgdGV4dHVyZXMgPSBleHRyYWN0RnJvbUNhY2hlKCBtZXRhLnRleHR1cmVzICk7XG5cdFx0XHR2YXIgaW1hZ2VzID0gZXh0cmFjdEZyb21DYWNoZSggbWV0YS5pbWFnZXMgKTtcblxuXHRcdFx0aWYgKCBnZW9tZXRyaWVzLmxlbmd0aCA+IDAgKSBvdXRwdXQuZ2VvbWV0cmllcyA9IGdlb21ldHJpZXM7XG5cdFx0XHRpZiAoIG1hdGVyaWFscy5sZW5ndGggPiAwICkgb3V0cHV0Lm1hdGVyaWFscyA9IG1hdGVyaWFscztcblx0XHRcdGlmICggdGV4dHVyZXMubGVuZ3RoID4gMCApIG91dHB1dC50ZXh0dXJlcyA9IHRleHR1cmVzO1xuXHRcdFx0aWYgKCBpbWFnZXMubGVuZ3RoID4gMCApIG91dHB1dC5pbWFnZXMgPSBpbWFnZXM7XG5cblx0XHR9XG5cblx0XHRvdXRwdXQub2JqZWN0ID0gb2JqZWN0O1xuXG5cdFx0cmV0dXJuIG91dHB1dDtcblxuXHRcdC8vIGV4dHJhY3QgZGF0YSBmcm9tIHRoZSBjYWNoZSBoYXNoXG5cdFx0Ly8gcmVtb3ZlIG1ldGFkYXRhIG9uIGVhY2ggaXRlbVxuXHRcdC8vIGFuZCByZXR1cm4gYXMgYXJyYXlcblx0XHRmdW5jdGlvbiBleHRyYWN0RnJvbUNhY2hlKCBjYWNoZSApIHtcblxuXHRcdFx0dmFyIHZhbHVlcyA9IFtdO1xuXHRcdFx0Zm9yICggdmFyIGtleSBpbiBjYWNoZSApIHtcblxuXHRcdFx0XHR2YXIgZGF0YSA9IGNhY2hlWyBrZXkgXTtcblx0XHRcdFx0ZGVsZXRlIGRhdGEubWV0YWRhdGE7XG5cdFx0XHRcdHZhbHVlcy5wdXNoKCBkYXRhICk7XG5cblx0XHRcdH1cblx0XHRcdHJldHVybiB2YWx1ZXM7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCByZWN1cnNpdmUgKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KCB0aGlzLCByZWN1cnNpdmUgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlLCByZWN1cnNpdmUgKSB7XG5cblx0XHRpZiAoIHJlY3Vyc2l2ZSA9PT0gdW5kZWZpbmVkICkgcmVjdXJzaXZlID0gdHJ1ZTtcblxuXHRcdHRoaXMubmFtZSA9IHNvdXJjZS5uYW1lO1xuXG5cdFx0dGhpcy51cC5jb3B5KCBzb3VyY2UudXAgKTtcblxuXHRcdHRoaXMucG9zaXRpb24uY29weSggc291cmNlLnBvc2l0aW9uICk7XG5cdFx0dGhpcy5xdWF0ZXJuaW9uLmNvcHkoIHNvdXJjZS5xdWF0ZXJuaW9uICk7XG5cdFx0dGhpcy5zY2FsZS5jb3B5KCBzb3VyY2Uuc2NhbGUgKTtcblxuXHRcdHRoaXMubWF0cml4LmNvcHkoIHNvdXJjZS5tYXRyaXggKTtcblx0XHR0aGlzLm1hdHJpeFdvcmxkLmNvcHkoIHNvdXJjZS5tYXRyaXhXb3JsZCApO1xuXG5cdFx0dGhpcy5tYXRyaXhBdXRvVXBkYXRlID0gc291cmNlLm1hdHJpeEF1dG9VcGRhdGU7XG5cdFx0dGhpcy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlID0gc291cmNlLm1hdHJpeFdvcmxkTmVlZHNVcGRhdGU7XG5cblx0XHR0aGlzLmxheWVycy5tYXNrID0gc291cmNlLmxheWVycy5tYXNrO1xuXHRcdHRoaXMudmlzaWJsZSA9IHNvdXJjZS52aXNpYmxlO1xuXG5cdFx0dGhpcy5jYXN0U2hhZG93ID0gc291cmNlLmNhc3RTaGFkb3c7XG5cdFx0dGhpcy5yZWNlaXZlU2hhZG93ID0gc291cmNlLnJlY2VpdmVTaGFkb3c7XG5cblx0XHR0aGlzLmZydXN0dW1DdWxsZWQgPSBzb3VyY2UuZnJ1c3R1bUN1bGxlZDtcblx0XHR0aGlzLnJlbmRlck9yZGVyID0gc291cmNlLnJlbmRlck9yZGVyO1xuXG5cdFx0dGhpcy51c2VyRGF0YSA9IEpTT04ucGFyc2UoIEpTT04uc3RyaW5naWZ5KCBzb3VyY2UudXNlckRhdGEgKSApO1xuXG5cdFx0aWYgKCByZWN1cnNpdmUgPT09IHRydWUgKSB7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHNvdXJjZS5jaGlsZHJlbi5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGNoaWxkID0gc291cmNlLmNoaWxkcmVuWyBpIF07XG5cdFx0XHRcdHRoaXMuYWRkKCBjaGlsZC5jbG9uZSgpICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYmhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW9cbiAqL1xuXG5mdW5jdGlvbiBMaW5lMyggc3RhcnQsIGVuZCApIHtcblxuXHR0aGlzLnN0YXJ0ID0gKCBzdGFydCAhPT0gdW5kZWZpbmVkICkgPyBzdGFydCA6IG5ldyBWZWN0b3IzKCk7XG5cdHRoaXMuZW5kID0gKCBlbmQgIT09IHVuZGVmaW5lZCApID8gZW5kIDogbmV3IFZlY3RvcjMoKTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBMaW5lMy5wcm90b3R5cGUsIHtcblxuXHRzZXQ6IGZ1bmN0aW9uICggc3RhcnQsIGVuZCApIHtcblxuXHRcdHRoaXMuc3RhcnQuY29weSggc3RhcnQgKTtcblx0XHR0aGlzLmVuZC5jb3B5KCBlbmQgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggbGluZSApIHtcblxuXHRcdHRoaXMuc3RhcnQuY29weSggbGluZS5zdGFydCApO1xuXHRcdHRoaXMuZW5kLmNvcHkoIGxpbmUuZW5kICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldENlbnRlcjogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdHJldHVybiByZXN1bHQuYWRkVmVjdG9ycyggdGhpcy5zdGFydCwgdGhpcy5lbmQgKS5tdWx0aXBseVNjYWxhciggMC41ICk7XG5cblx0fSxcblxuXHRkZWx0YTogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdHJldHVybiByZXN1bHQuc3ViVmVjdG9ycyggdGhpcy5lbmQsIHRoaXMuc3RhcnQgKTtcblxuXHR9LFxuXG5cdGRpc3RhbmNlU3E6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG9TcXVhcmVkKCB0aGlzLmVuZCApO1xuXG5cdH0sXG5cblx0ZGlzdGFuY2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG8oIHRoaXMuZW5kICk7XG5cblx0fSxcblxuXHRhdDogZnVuY3Rpb24gKCB0LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIHRoaXMuZGVsdGEoIHJlc3VsdCApLm11bHRpcGx5U2NhbGFyKCB0ICkuYWRkKCB0aGlzLnN0YXJ0ICk7XG5cblx0fSxcblxuXHRjbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgc3RhcnRQID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgc3RhcnRFbmQgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIoIHBvaW50LCBjbGFtcFRvTGluZSApIHtcblxuXHRcdFx0c3RhcnRQLnN1YlZlY3RvcnMoIHBvaW50LCB0aGlzLnN0YXJ0ICk7XG5cdFx0XHRzdGFydEVuZC5zdWJWZWN0b3JzKCB0aGlzLmVuZCwgdGhpcy5zdGFydCApO1xuXG5cdFx0XHR2YXIgc3RhcnRFbmQyID0gc3RhcnRFbmQuZG90KCBzdGFydEVuZCApO1xuXHRcdFx0dmFyIHN0YXJ0RW5kX3N0YXJ0UCA9IHN0YXJ0RW5kLmRvdCggc3RhcnRQICk7XG5cblx0XHRcdHZhciB0ID0gc3RhcnRFbmRfc3RhcnRQIC8gc3RhcnRFbmQyO1xuXG5cdFx0XHRpZiAoIGNsYW1wVG9MaW5lICkge1xuXG5cdFx0XHRcdHQgPSBfTWF0aC5jbGFtcCggdCwgMCwgMSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0O1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Y2xvc2VzdFBvaW50VG9Qb2ludDogZnVuY3Rpb24gKCBwb2ludCwgY2xhbXBUb0xpbmUsIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHQgPSB0aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIoIHBvaW50LCBjbGFtcFRvTGluZSApO1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gdGhpcy5kZWx0YSggcmVzdWx0ICkubXVsdGlwbHlTY2FsYXIoIHQgKS5hZGQoIHRoaXMuc3RhcnQgKTtcblxuXHR9LFxuXG5cdGFwcGx5TWF0cml4NDogZnVuY3Rpb24gKCBtYXRyaXggKSB7XG5cblx0XHR0aGlzLnN0YXJ0LmFwcGx5TWF0cml4NCggbWF0cml4ICk7XG5cdFx0dGhpcy5lbmQuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIGxpbmUgKSB7XG5cblx0XHRyZXR1cm4gbGluZS5zdGFydC5lcXVhbHMoIHRoaXMuc3RhcnQgKSAmJiBsaW5lLmVuZC5lcXVhbHMoIHRoaXMuZW5kICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBUcmlhbmdsZSggYSwgYiwgYyApIHtcblxuXHR0aGlzLmEgPSAoIGEgIT09IHVuZGVmaW5lZCApID8gYSA6IG5ldyBWZWN0b3IzKCk7XG5cdHRoaXMuYiA9ICggYiAhPT0gdW5kZWZpbmVkICkgPyBiIDogbmV3IFZlY3RvcjMoKTtcblx0dGhpcy5jID0gKCBjICE9PSB1bmRlZmluZWQgKSA/IGMgOiBuZXcgVmVjdG9yMygpO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFRyaWFuZ2xlLCB7XG5cblx0bm9ybWFsOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjAgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIG5vcm1hbCggYSwgYiwgYywgb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXG5cdFx0XHRyZXN1bHQuc3ViVmVjdG9ycyggYywgYiApO1xuXHRcdFx0djAuc3ViVmVjdG9ycyggYSwgYiApO1xuXHRcdFx0cmVzdWx0LmNyb3NzKCB2MCApO1xuXG5cdFx0XHR2YXIgcmVzdWx0TGVuZ3RoU3EgPSByZXN1bHQubGVuZ3RoU3EoKTtcblx0XHRcdGlmICggcmVzdWx0TGVuZ3RoU3EgPiAwICkge1xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQubXVsdGlwbHlTY2FsYXIoIDEgLyBNYXRoLnNxcnQoIHJlc3VsdExlbmd0aFNxICkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0LnNldCggMCwgMCwgMCApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Ly8gc3RhdGljL2luc3RhbmNlIG1ldGhvZCB0byBjYWxjdWxhdGUgYmFyeWNlbnRyaWMgY29vcmRpbmF0ZXNcblx0Ly8gYmFzZWQgb246IGh0dHA6Ly93d3cuYmxhY2twYXduLmNvbS90ZXh0cy9wb2ludGlucG9seS9kZWZhdWx0Lmh0bWxcblx0YmFyeWNvb3JkRnJvbVBvaW50OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjAgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIHYyID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBiYXJ5Y29vcmRGcm9tUG9pbnQoIHBvaW50LCBhLCBiLCBjLCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdFx0djAuc3ViVmVjdG9ycyggYywgYSApO1xuXHRcdFx0djEuc3ViVmVjdG9ycyggYiwgYSApO1xuXHRcdFx0djIuc3ViVmVjdG9ycyggcG9pbnQsIGEgKTtcblxuXHRcdFx0dmFyIGRvdDAwID0gdjAuZG90KCB2MCApO1xuXHRcdFx0dmFyIGRvdDAxID0gdjAuZG90KCB2MSApO1xuXHRcdFx0dmFyIGRvdDAyID0gdjAuZG90KCB2MiApO1xuXHRcdFx0dmFyIGRvdDExID0gdjEuZG90KCB2MSApO1xuXHRcdFx0dmFyIGRvdDEyID0gdjEuZG90KCB2MiApO1xuXG5cdFx0XHR2YXIgZGVub20gPSAoIGRvdDAwICogZG90MTEgLSBkb3QwMSAqIGRvdDAxICk7XG5cblx0XHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXG5cdFx0XHQvLyBjb2xsaW5lYXIgb3Igc2luZ3VsYXIgdHJpYW5nbGVcblx0XHRcdGlmICggZGVub20gPT09IDAgKSB7XG5cblx0XHRcdFx0Ly8gYXJiaXRyYXJ5IGxvY2F0aW9uIG91dHNpZGUgb2YgdHJpYW5nbGU/XG5cdFx0XHRcdC8vIG5vdCBzdXJlIGlmIHRoaXMgaXMgdGhlIGJlc3QgaWRlYSwgbWF5YmUgc2hvdWxkIGJlIHJldHVybmluZyB1bmRlZmluZWRcblx0XHRcdFx0cmV0dXJuIHJlc3VsdC5zZXQoIC0gMiwgLSAxLCAtIDEgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgaW52RGVub20gPSAxIC8gZGVub207XG5cdFx0XHR2YXIgdSA9ICggZG90MTEgKiBkb3QwMiAtIGRvdDAxICogZG90MTIgKSAqIGludkRlbm9tO1xuXHRcdFx0dmFyIHYgPSAoIGRvdDAwICogZG90MTIgLSBkb3QwMSAqIGRvdDAyICkgKiBpbnZEZW5vbTtcblxuXHRcdFx0Ly8gYmFyeWNlbnRyaWMgY29vcmRpbmF0ZXMgbXVzdCBhbHdheXMgc3VtIHRvIDFcblx0XHRcdHJldHVybiByZXN1bHQuc2V0KCAxIC0gdSAtIHYsIHYsIHUgKTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGNvbnRhaW5zUG9pbnQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gY29udGFpbnNQb2ludCggcG9pbnQsIGEsIGIsIGMgKSB7XG5cblx0XHRcdHZhciByZXN1bHQgPSBUcmlhbmdsZS5iYXJ5Y29vcmRGcm9tUG9pbnQoIHBvaW50LCBhLCBiLCBjLCB2MSApO1xuXG5cdFx0XHRyZXR1cm4gKCByZXN1bHQueCA+PSAwICkgJiYgKCByZXN1bHQueSA+PSAwICkgJiYgKCAoIHJlc3VsdC54ICsgcmVzdWx0LnkgKSA8PSAxICk7XG5cblx0XHR9O1xuXG5cdH0oKVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIFRyaWFuZ2xlLnByb3RvdHlwZSwge1xuXG5cdHNldDogZnVuY3Rpb24gKCBhLCBiLCBjICkge1xuXG5cdFx0dGhpcy5hLmNvcHkoIGEgKTtcblx0XHR0aGlzLmIuY29weSggYiApO1xuXHRcdHRoaXMuYy5jb3B5KCBjICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21Qb2ludHNBbmRJbmRpY2VzOiBmdW5jdGlvbiAoIHBvaW50cywgaTAsIGkxLCBpMiApIHtcblxuXHRcdHRoaXMuYS5jb3B5KCBwb2ludHNbIGkwIF0gKTtcblx0XHR0aGlzLmIuY29weSggcG9pbnRzWyBpMSBdICk7XG5cdFx0dGhpcy5jLmNvcHkoIHBvaW50c1sgaTIgXSApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCB0cmlhbmdsZSApIHtcblxuXHRcdHRoaXMuYS5jb3B5KCB0cmlhbmdsZS5hICk7XG5cdFx0dGhpcy5iLmNvcHkoIHRyaWFuZ2xlLmIgKTtcblx0XHR0aGlzLmMuY29weSggdHJpYW5nbGUuYyApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRhcmVhOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjAgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gYXJlYSgpIHtcblxuXHRcdFx0djAuc3ViVmVjdG9ycyggdGhpcy5jLCB0aGlzLmIgKTtcblx0XHRcdHYxLnN1YlZlY3RvcnMoIHRoaXMuYSwgdGhpcy5iICk7XG5cblx0XHRcdHJldHVybiB2MC5jcm9zcyggdjEgKS5sZW5ndGgoKSAqIDAuNTtcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdG1pZHBvaW50OiBmdW5jdGlvbiAoIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IG9wdGlvbmFsVGFyZ2V0IHx8IG5ldyBWZWN0b3IzKCk7XG5cdFx0cmV0dXJuIHJlc3VsdC5hZGRWZWN0b3JzKCB0aGlzLmEsIHRoaXMuYiApLmFkZCggdGhpcy5jICkubXVsdGlwbHlTY2FsYXIoIDEgLyAzICk7XG5cblx0fSxcblxuXHRub3JtYWw6IGZ1bmN0aW9uICggb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHRyZXR1cm4gVHJpYW5nbGUubm9ybWFsKCB0aGlzLmEsIHRoaXMuYiwgdGhpcy5jLCBvcHRpb25hbFRhcmdldCApO1xuXG5cdH0sXG5cblx0cGxhbmU6IGZ1bmN0aW9uICggb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFBsYW5lKCk7XG5cblx0XHRyZXR1cm4gcmVzdWx0LnNldEZyb21Db3BsYW5hclBvaW50cyggdGhpcy5hLCB0aGlzLmIsIHRoaXMuYyApO1xuXG5cdH0sXG5cblx0YmFyeWNvb3JkRnJvbVBvaW50OiBmdW5jdGlvbiAoIHBvaW50LCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdHJldHVybiBUcmlhbmdsZS5iYXJ5Y29vcmRGcm9tUG9pbnQoIHBvaW50LCB0aGlzLmEsIHRoaXMuYiwgdGhpcy5jLCBvcHRpb25hbFRhcmdldCApO1xuXG5cdH0sXG5cblx0Y29udGFpbnNQb2ludDogZnVuY3Rpb24gKCBwb2ludCApIHtcblxuXHRcdHJldHVybiBUcmlhbmdsZS5jb250YWluc1BvaW50KCBwb2ludCwgdGhpcy5hLCB0aGlzLmIsIHRoaXMuYyApO1xuXG5cdH0sXG5cblx0Y2xvc2VzdFBvaW50VG9Qb2ludDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHBsYW5lID0gbmV3IFBsYW5lKCk7XG5cdFx0dmFyIGVkZ2VMaXN0ID0gWyBuZXcgTGluZTMoKSwgbmV3IExpbmUzKCksIG5ldyBMaW5lMygpIF07XG5cdFx0dmFyIHByb2plY3RlZFBvaW50ID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgY2xvc2VzdFBvaW50ID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBjbG9zZXN0UG9pbnRUb1BvaW50KCBwb2ludCwgb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHRcdHZhciByZXN1bHQgPSBvcHRpb25hbFRhcmdldCB8fCBuZXcgVmVjdG9yMygpO1xuXHRcdFx0dmFyIG1pbkRpc3RhbmNlID0gSW5maW5pdHk7XG5cblx0XHRcdC8vIHByb2plY3QgdGhlIHBvaW50IG9udG8gdGhlIHBsYW5lIG9mIHRoZSB0cmlhbmdsZVxuXG5cdFx0XHRwbGFuZS5zZXRGcm9tQ29wbGFuYXJQb2ludHMoIHRoaXMuYSwgdGhpcy5iLCB0aGlzLmMgKTtcblx0XHRcdHBsYW5lLnByb2plY3RQb2ludCggcG9pbnQsIHByb2plY3RlZFBvaW50ICk7XG5cblx0XHRcdC8vIGNoZWNrIGlmIHRoZSBwcm9qZWN0aW9uIGxpZXMgd2l0aGluIHRoZSB0cmlhbmdsZVxuXG5cdFx0XHRpZiggdGhpcy5jb250YWluc1BvaW50KCBwcm9qZWN0ZWRQb2ludCApID09PSB0cnVlICkge1xuXG5cdFx0XHRcdC8vIGlmIHNvLCB0aGlzIGlzIHRoZSBjbG9zZXN0IHBvaW50XG5cblx0XHRcdFx0cmVzdWx0LmNvcHkoIHByb2plY3RlZFBvaW50ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gaWYgbm90LCB0aGUgcG9pbnQgZmFsbHMgb3V0c2lkZSB0aGUgdHJpYW5nbGUuIHRoZSByZXN1bHQgaXMgdGhlIGNsb3Nlc3QgcG9pbnQgdG8gdGhlIHRyaWFuZ2xlJ3MgZWRnZXMgb3IgdmVydGljZXNcblxuXHRcdFx0XHRlZGdlTGlzdFsgMCBdLnNldCggdGhpcy5hLCB0aGlzLmIgKTtcblx0XHRcdFx0ZWRnZUxpc3RbIDEgXS5zZXQoIHRoaXMuYiwgdGhpcy5jICk7XG5cdFx0XHRcdGVkZ2VMaXN0WyAyIF0uc2V0KCB0aGlzLmMsIHRoaXMuYSApO1xuXG5cdFx0XHRcdGZvciggdmFyIGkgPSAwOyBpIDwgZWRnZUxpc3QubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdFx0ZWRnZUxpc3RbIGkgXS5jbG9zZXN0UG9pbnRUb1BvaW50KCBwcm9qZWN0ZWRQb2ludCwgdHJ1ZSwgY2xvc2VzdFBvaW50ICk7XG5cblx0XHRcdFx0XHR2YXIgZGlzdGFuY2UgPSBwcm9qZWN0ZWRQb2ludC5kaXN0YW5jZVRvU3F1YXJlZCggY2xvc2VzdFBvaW50ICk7XG5cblx0XHRcdFx0XHRpZiggZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSApIHtcblxuXHRcdFx0XHRcdFx0bWluRGlzdGFuY2UgPSBkaXN0YW5jZTtcblxuXHRcdFx0XHRcdFx0cmVzdWx0LmNvcHkoIGNsb3Nlc3RQb2ludCApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0ZXF1YWxzOiBmdW5jdGlvbiAoIHRyaWFuZ2xlICkge1xuXG5cdFx0cmV0dXJuIHRyaWFuZ2xlLmEuZXF1YWxzKCB0aGlzLmEgKSAmJiB0cmlhbmdsZS5iLmVxdWFscyggdGhpcy5iICkgJiYgdHJpYW5nbGUuYy5lcXVhbHMoIHRoaXMuYyApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICovXG5cbmZ1bmN0aW9uIEZhY2UzKCBhLCBiLCBjLCBub3JtYWwsIGNvbG9yLCBtYXRlcmlhbEluZGV4ICkge1xuXG5cdHRoaXMuYSA9IGE7XG5cdHRoaXMuYiA9IGI7XG5cdHRoaXMuYyA9IGM7XG5cblx0dGhpcy5ub3JtYWwgPSAoIG5vcm1hbCAmJiBub3JtYWwuaXNWZWN0b3IzICkgPyBub3JtYWwgOiBuZXcgVmVjdG9yMygpO1xuXHR0aGlzLnZlcnRleE5vcm1hbHMgPSBBcnJheS5pc0FycmF5KCBub3JtYWwgKSA/IG5vcm1hbCA6IFtdO1xuXG5cdHRoaXMuY29sb3IgPSAoIGNvbG9yICYmIGNvbG9yLmlzQ29sb3IgKSA/IGNvbG9yIDogbmV3IENvbG9yKCk7XG5cdHRoaXMudmVydGV4Q29sb3JzID0gQXJyYXkuaXNBcnJheSggY29sb3IgKSA/IGNvbG9yIDogW107XG5cblx0dGhpcy5tYXRlcmlhbEluZGV4ID0gbWF0ZXJpYWxJbmRleCAhPT0gdW5kZWZpbmVkID8gbWF0ZXJpYWxJbmRleCA6IDA7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggRmFjZTMucHJvdG90eXBlLCB7XG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0dGhpcy5hID0gc291cmNlLmE7XG5cdFx0dGhpcy5iID0gc291cmNlLmI7XG5cdFx0dGhpcy5jID0gc291cmNlLmM7XG5cblx0XHR0aGlzLm5vcm1hbC5jb3B5KCBzb3VyY2Uubm9ybWFsICk7XG5cdFx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblxuXHRcdHRoaXMubWF0ZXJpYWxJbmRleCA9IHNvdXJjZS5tYXRlcmlhbEluZGV4O1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHNvdXJjZS52ZXJ0ZXhOb3JtYWxzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLnZlcnRleE5vcm1hbHNbIGkgXSA9IHNvdXJjZS52ZXJ0ZXhOb3JtYWxzWyBpIF0uY2xvbmUoKTtcblxuXHRcdH1cblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSBzb3VyY2UudmVydGV4Q29sb3JzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLnZlcnRleENvbG9yc1sgaSBdID0gc291cmNlLnZlcnRleENvbG9yc1sgaSBdLmNsb25lKCk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqXG4gKiBwYXJhbWV0ZXJzID0ge1xuICogIGNvbG9yOiA8aGV4PixcbiAqICBvcGFjaXR5OiA8ZmxvYXQ+LFxuICogIG1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKiAgbGlnaHRNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKiAgbGlnaHRNYXBJbnRlbnNpdHk6IDxmbG9hdD5cbiAqXG4gKiAgYW9NYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKiAgYW9NYXBJbnRlbnNpdHk6IDxmbG9hdD5cbiAqXG4gKiAgc3BlY3VsYXJNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGFscGhhTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBlbnZNYXA6IG5ldyBUSFJFRS5UZXh0dXJlQ3ViZSggW3Bvc3gsIG5lZ3gsIHBvc3ksIG5lZ3ksIHBvc3osIG5lZ3pdICksXG4gKiAgY29tYmluZTogVEhSRUUuTXVsdGlwbHksXG4gKiAgcmVmbGVjdGl2aXR5OiA8ZmxvYXQ+LFxuICogIHJlZnJhY3Rpb25SYXRpbzogPGZsb2F0PixcbiAqXG4gKiAgc2hhZGluZzogVEhSRUUuU21vb3RoU2hhZGluZyxcbiAqICBkZXB0aFRlc3Q6IDxib29sPixcbiAqICBkZXB0aFdyaXRlOiA8Ym9vbD4sXG4gKlxuICogIHdpcmVmcmFtZTogPGJvb2xlYW4+LFxuICogIHdpcmVmcmFtZUxpbmV3aWR0aDogPGZsb2F0PixcbiAqXG4gKiAgc2tpbm5pbmc6IDxib29sPixcbiAqICBtb3JwaFRhcmdldHM6IDxib29sPlxuICogfVxuICovXG5cbmZ1bmN0aW9uIE1lc2hCYXNpY01hdGVyaWFsKCBwYXJhbWV0ZXJzICkge1xuXG5cdE1hdGVyaWFsLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnTWVzaEJhc2ljTWF0ZXJpYWwnO1xuXG5cdHRoaXMuY29sb3IgPSBuZXcgQ29sb3IoIDB4ZmZmZmZmICk7IC8vIGVtaXNzaXZlXG5cblx0dGhpcy5tYXAgPSBudWxsO1xuXG5cdHRoaXMubGlnaHRNYXAgPSBudWxsO1xuXHR0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuYW9NYXAgPSBudWxsO1xuXHR0aGlzLmFvTWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuc3BlY3VsYXJNYXAgPSBudWxsO1xuXG5cdHRoaXMuYWxwaGFNYXAgPSBudWxsO1xuXG5cdHRoaXMuZW52TWFwID0gbnVsbDtcblx0dGhpcy5jb21iaW5lID0gTXVsdGlwbHlPcGVyYXRpb247XG5cdHRoaXMucmVmbGVjdGl2aXR5ID0gMTtcblx0dGhpcy5yZWZyYWN0aW9uUmF0aW8gPSAwLjk4O1xuXG5cdHRoaXMud2lyZWZyYW1lID0gZmFsc2U7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gMTtcblx0dGhpcy53aXJlZnJhbWVMaW5lY2FwID0gJ3JvdW5kJztcblx0dGhpcy53aXJlZnJhbWVMaW5lam9pbiA9ICdyb3VuZCc7XG5cblx0dGhpcy5za2lubmluZyA9IGZhbHNlO1xuXHR0aGlzLm1vcnBoVGFyZ2V0cyA9IGZhbHNlO1xuXG5cdHRoaXMubGlnaHRzID0gZmFsc2U7XG5cblx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5NZXNoQmFzaWNNYXRlcmlhbC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBNYXRlcmlhbC5wcm90b3R5cGUgKTtcbk1lc2hCYXNpY01hdGVyaWFsLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IE1lc2hCYXNpY01hdGVyaWFsO1xuXG5NZXNoQmFzaWNNYXRlcmlhbC5wcm90b3R5cGUuaXNNZXNoQmFzaWNNYXRlcmlhbCA9IHRydWU7XG5cbk1lc2hCYXNpY01hdGVyaWFsLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0TWF0ZXJpYWwucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblxuXHR0aGlzLm1hcCA9IHNvdXJjZS5tYXA7XG5cblx0dGhpcy5saWdodE1hcCA9IHNvdXJjZS5saWdodE1hcDtcblx0dGhpcy5saWdodE1hcEludGVuc2l0eSA9IHNvdXJjZS5saWdodE1hcEludGVuc2l0eTtcblxuXHR0aGlzLmFvTWFwID0gc291cmNlLmFvTWFwO1xuXHR0aGlzLmFvTWFwSW50ZW5zaXR5ID0gc291cmNlLmFvTWFwSW50ZW5zaXR5O1xuXG5cdHRoaXMuc3BlY3VsYXJNYXAgPSBzb3VyY2Uuc3BlY3VsYXJNYXA7XG5cblx0dGhpcy5hbHBoYU1hcCA9IHNvdXJjZS5hbHBoYU1hcDtcblxuXHR0aGlzLmVudk1hcCA9IHNvdXJjZS5lbnZNYXA7XG5cdHRoaXMuY29tYmluZSA9IHNvdXJjZS5jb21iaW5lO1xuXHR0aGlzLnJlZmxlY3Rpdml0eSA9IHNvdXJjZS5yZWZsZWN0aXZpdHk7XG5cdHRoaXMucmVmcmFjdGlvblJhdGlvID0gc291cmNlLnJlZnJhY3Rpb25SYXRpbztcblxuXHR0aGlzLndpcmVmcmFtZSA9IHNvdXJjZS53aXJlZnJhbWU7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gc291cmNlLndpcmVmcmFtZUxpbmV3aWR0aDtcblx0dGhpcy53aXJlZnJhbWVMaW5lY2FwID0gc291cmNlLndpcmVmcmFtZUxpbmVjYXA7XG5cdHRoaXMud2lyZWZyYW1lTGluZWpvaW4gPSBzb3VyY2Uud2lyZWZyYW1lTGluZWpvaW47XG5cblx0dGhpcy5za2lubmluZyA9IHNvdXJjZS5za2lubmluZztcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXG5cdHJldHVybiB0aGlzO1xuXG59O1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyQXR0cmlidXRlKCBhcnJheSwgaXRlbVNpemUsIG5vcm1hbGl6ZWQgKSB7XG5cblx0aWYgKCBBcnJheS5pc0FycmF5KCBhcnJheSApICkge1xuXG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvciggJ1RIUkVFLkJ1ZmZlckF0dHJpYnV0ZTogYXJyYXkgc2hvdWxkIGJlIGEgVHlwZWQgQXJyYXkuJyApO1xuXG5cdH1cblxuXHR0aGlzLnV1aWQgPSBfTWF0aC5nZW5lcmF0ZVVVSUQoKTtcblxuXHR0aGlzLmFycmF5ID0gYXJyYXk7XG5cdHRoaXMuaXRlbVNpemUgPSBpdGVtU2l6ZTtcblx0dGhpcy5jb3VudCA9IGFycmF5ICE9PSB1bmRlZmluZWQgPyBhcnJheS5sZW5ndGggLyBpdGVtU2l6ZSA6IDA7XG5cdHRoaXMubm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQgPT09IHRydWU7XG5cblx0dGhpcy5keW5hbWljID0gZmFsc2U7XG5cdHRoaXMudXBkYXRlUmFuZ2UgPSB7IG9mZnNldDogMCwgY291bnQ6IC0gMSB9O1xuXG5cdHRoaXMub25VcGxvYWRDYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuXG5cdHRoaXMudmVyc2lvbiA9IDA7XG5cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KCBCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLCAnbmVlZHNVcGRhdGUnLCB7XG5cblx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0aWYgKCB2YWx1ZSA9PT0gdHJ1ZSApIHRoaXMudmVyc2lvbiArKztcblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSwge1xuXG5cdGlzQnVmZmVyQXR0cmlidXRlOiB0cnVlLFxuXG5cdHNldEFycmF5OiBmdW5jdGlvbiAoIGFycmF5ICkge1xuXG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCBhcnJheSApICkge1xuXG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCAnVEhSRUUuQnVmZmVyQXR0cmlidXRlOiBhcnJheSBzaG91bGQgYmUgYSBUeXBlZCBBcnJheS4nICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLmNvdW50ID0gYXJyYXkgIT09IHVuZGVmaW5lZCA/IGFycmF5Lmxlbmd0aCAvIHRoaXMuaXRlbVNpemUgOiAwO1xuXHRcdHRoaXMuYXJyYXkgPSBhcnJheTtcblxuXHR9LFxuXG5cdHNldER5bmFtaWM6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLmR5bmFtaWMgPSB2YWx1ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR0aGlzLmFycmF5ID0gbmV3IHNvdXJjZS5hcnJheS5jb25zdHJ1Y3Rvciggc291cmNlLmFycmF5ICk7XG5cdFx0dGhpcy5pdGVtU2l6ZSA9IHNvdXJjZS5pdGVtU2l6ZTtcblx0XHR0aGlzLmNvdW50ID0gc291cmNlLmNvdW50O1xuXHRcdHRoaXMubm9ybWFsaXplZCA9IHNvdXJjZS5ub3JtYWxpemVkO1xuXG5cdFx0dGhpcy5keW5hbWljID0gc291cmNlLmR5bmFtaWM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvcHlBdDogZnVuY3Rpb24gKCBpbmRleDEsIGF0dHJpYnV0ZSwgaW5kZXgyICkge1xuXG5cdFx0aW5kZXgxICo9IHRoaXMuaXRlbVNpemU7XG5cdFx0aW5kZXgyICo9IGF0dHJpYnV0ZS5pdGVtU2l6ZTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IHRoaXMuaXRlbVNpemU7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLmFycmF5WyBpbmRleDEgKyBpIF0gPSBhdHRyaWJ1dGUuYXJyYXlbIGluZGV4MiArIGkgXTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weUFycmF5OiBmdW5jdGlvbiAoIGFycmF5ICkge1xuXG5cdFx0dGhpcy5hcnJheS5zZXQoIGFycmF5ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvcHlDb2xvcnNBcnJheTogZnVuY3Rpb24gKCBjb2xvcnMgKSB7XG5cblx0XHR2YXIgYXJyYXkgPSB0aGlzLmFycmF5LCBvZmZzZXQgPSAwO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gY29sb3JzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBjb2xvciA9IGNvbG9yc1sgaSBdO1xuXG5cdFx0XHRpZiAoIGNvbG9yID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyQXR0cmlidXRlLmNvcHlDb2xvcnNBcnJheSgpOiBjb2xvciBpcyB1bmRlZmluZWQnLCBpICk7XG5cdFx0XHRcdGNvbG9yID0gbmV3IENvbG9yKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0YXJyYXlbIG9mZnNldCArKyBdID0gY29sb3Iucjtcblx0XHRcdGFycmF5WyBvZmZzZXQgKysgXSA9IGNvbG9yLmc7XG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSBjb2xvci5iO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjb3B5SW5kaWNlc0FycmF5OiBmdW5jdGlvbiAoIGluZGljZXMgKSB7XG5cblx0XHR2YXIgYXJyYXkgPSB0aGlzLmFycmF5LCBvZmZzZXQgPSAwO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gaW5kaWNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgaW5kZXggPSBpbmRpY2VzWyBpIF07XG5cblx0XHRcdGFycmF5WyBvZmZzZXQgKysgXSA9IGluZGV4LmE7XG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSBpbmRleC5iO1xuXHRcdFx0YXJyYXlbIG9mZnNldCArKyBdID0gaW5kZXguYztcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weVZlY3RvcjJzQXJyYXk6IGZ1bmN0aW9uICggdmVjdG9ycyApIHtcblxuXHRcdHZhciBhcnJheSA9IHRoaXMuYXJyYXksIG9mZnNldCA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSB2ZWN0b3JzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciB2ZWN0b3IgPSB2ZWN0b3JzWyBpIF07XG5cblx0XHRcdGlmICggdmVjdG9yID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyQXR0cmlidXRlLmNvcHlWZWN0b3Iyc0FycmF5KCk6IHZlY3RvciBpcyB1bmRlZmluZWQnLCBpICk7XG5cdFx0XHRcdHZlY3RvciA9IG5ldyBWZWN0b3IyKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0YXJyYXlbIG9mZnNldCArKyBdID0gdmVjdG9yLng7XG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSB2ZWN0b3IueTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weVZlY3RvcjNzQXJyYXk6IGZ1bmN0aW9uICggdmVjdG9ycyApIHtcblxuXHRcdHZhciBhcnJheSA9IHRoaXMuYXJyYXksIG9mZnNldCA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSB2ZWN0b3JzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciB2ZWN0b3IgPSB2ZWN0b3JzWyBpIF07XG5cblx0XHRcdGlmICggdmVjdG9yID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyQXR0cmlidXRlLmNvcHlWZWN0b3Izc0FycmF5KCk6IHZlY3RvciBpcyB1bmRlZmluZWQnLCBpICk7XG5cdFx0XHRcdHZlY3RvciA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0YXJyYXlbIG9mZnNldCArKyBdID0gdmVjdG9yLng7XG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSB2ZWN0b3IueTtcblx0XHRcdGFycmF5WyBvZmZzZXQgKysgXSA9IHZlY3Rvci56O1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjb3B5VmVjdG9yNHNBcnJheTogZnVuY3Rpb24gKCB2ZWN0b3JzICkge1xuXG5cdFx0dmFyIGFycmF5ID0gdGhpcy5hcnJheSwgb2Zmc2V0ID0gMDtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IHZlY3RvcnMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIHZlY3RvciA9IHZlY3RvcnNbIGkgXTtcblxuXHRcdFx0aWYgKCB2ZWN0b3IgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJBdHRyaWJ1dGUuY29weVZlY3RvcjRzQXJyYXkoKTogdmVjdG9yIGlzIHVuZGVmaW5lZCcsIGkgKTtcblx0XHRcdFx0dmVjdG9yID0gbmV3IFZlY3RvcjQoKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSB2ZWN0b3IueDtcblx0XHRcdGFycmF5WyBvZmZzZXQgKysgXSA9IHZlY3Rvci55O1xuXHRcdFx0YXJyYXlbIG9mZnNldCArKyBdID0gdmVjdG9yLno7XG5cdFx0XHRhcnJheVsgb2Zmc2V0ICsrIF0gPSB2ZWN0b3IudztcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlLCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHRoaXMuYXJyYXkuc2V0KCB2YWx1ZSwgb2Zmc2V0ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldFg6IGZ1bmN0aW9uICggaW5kZXggKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5hcnJheVsgaW5kZXggKiB0aGlzLml0ZW1TaXplIF07XG5cblx0fSxcblxuXHRzZXRYOiBmdW5jdGlvbiAoIGluZGV4LCB4ICkge1xuXG5cdFx0dGhpcy5hcnJheVsgaW5kZXggKiB0aGlzLml0ZW1TaXplIF0gPSB4O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRnZXRZOiBmdW5jdGlvbiAoIGluZGV4ICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuYXJyYXlbIGluZGV4ICogdGhpcy5pdGVtU2l6ZSArIDEgXTtcblxuXHR9LFxuXG5cdHNldFk6IGZ1bmN0aW9uICggaW5kZXgsIHkgKSB7XG5cblx0XHR0aGlzLmFycmF5WyBpbmRleCAqIHRoaXMuaXRlbVNpemUgKyAxIF0gPSB5O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRnZXRaOiBmdW5jdGlvbiAoIGluZGV4ICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuYXJyYXlbIGluZGV4ICogdGhpcy5pdGVtU2l6ZSArIDIgXTtcblxuXHR9LFxuXG5cdHNldFo6IGZ1bmN0aW9uICggaW5kZXgsIHogKSB7XG5cblx0XHR0aGlzLmFycmF5WyBpbmRleCAqIHRoaXMuaXRlbVNpemUgKyAyIF0gPSB6O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRnZXRXOiBmdW5jdGlvbiAoIGluZGV4ICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuYXJyYXlbIGluZGV4ICogdGhpcy5pdGVtU2l6ZSArIDMgXTtcblxuXHR9LFxuXG5cdHNldFc6IGZ1bmN0aW9uICggaW5kZXgsIHcgKSB7XG5cblx0XHR0aGlzLmFycmF5WyBpbmRleCAqIHRoaXMuaXRlbVNpemUgKyAzIF0gPSB3O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRYWTogZnVuY3Rpb24gKCBpbmRleCwgeCwgeSApIHtcblxuXHRcdGluZGV4ICo9IHRoaXMuaXRlbVNpemU7XG5cblx0XHR0aGlzLmFycmF5WyBpbmRleCArIDAgXSA9IHg7XG5cdFx0dGhpcy5hcnJheVsgaW5kZXggKyAxIF0gPSB5O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRYWVo6IGZ1bmN0aW9uICggaW5kZXgsIHgsIHksIHogKSB7XG5cblx0XHRpbmRleCAqPSB0aGlzLml0ZW1TaXplO1xuXG5cdFx0dGhpcy5hcnJheVsgaW5kZXggKyAwIF0gPSB4O1xuXHRcdHRoaXMuYXJyYXlbIGluZGV4ICsgMSBdID0geTtcblx0XHR0aGlzLmFycmF5WyBpbmRleCArIDIgXSA9IHo7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFhZWlc6IGZ1bmN0aW9uICggaW5kZXgsIHgsIHksIHosIHcgKSB7XG5cblx0XHRpbmRleCAqPSB0aGlzLml0ZW1TaXplO1xuXG5cdFx0dGhpcy5hcnJheVsgaW5kZXggKyAwIF0gPSB4O1xuXHRcdHRoaXMuYXJyYXlbIGluZGV4ICsgMSBdID0geTtcblx0XHR0aGlzLmFycmF5WyBpbmRleCArIDIgXSA9IHo7XG5cdFx0dGhpcy5hcnJheVsgaW5kZXggKyAzIF0gPSB3O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRvblVwbG9hZDogZnVuY3Rpb24gKCBjYWxsYmFjayApIHtcblxuXHRcdHRoaXMub25VcGxvYWRDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCB0aGlzLmFycmF5LCB0aGlzLml0ZW1TaXplICkuY29weSggdGhpcyApO1xuXG5cdH1cblxufSApO1xuXG4vL1xuXG5mdW5jdGlvbiBJbnQ4QnVmZmVyQXR0cmlidXRlKCBhcnJheSwgaXRlbVNpemUgKSB7XG5cblx0QnVmZmVyQXR0cmlidXRlLmNhbGwoIHRoaXMsIG5ldyBJbnQ4QXJyYXkoIGFycmF5ICksIGl0ZW1TaXplICk7XG5cbn1cblxuSW50OEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlICk7XG5JbnQ4QnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEludDhCdWZmZXJBdHRyaWJ1dGU7XG5cblxuZnVuY3Rpb24gVWludDhCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRCdWZmZXJBdHRyaWJ1dGUuY2FsbCggdGhpcywgbmV3IFVpbnQ4QXJyYXkoIGFycmF5ICksIGl0ZW1TaXplICk7XG5cbn1cblxuVWludDhCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSApO1xuVWludDhCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVWludDhCdWZmZXJBdHRyaWJ1dGU7XG5cblxuZnVuY3Rpb24gVWludDhDbGFtcGVkQnVmZmVyQXR0cmlidXRlKCBhcnJheSwgaXRlbVNpemUgKSB7XG5cblx0QnVmZmVyQXR0cmlidXRlLmNhbGwoIHRoaXMsIG5ldyBVaW50OENsYW1wZWRBcnJheSggYXJyYXkgKSwgaXRlbVNpemUgKTtcblxufVxuXG5VaW50OENsYW1wZWRCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSApO1xuVWludDhDbGFtcGVkQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFVpbnQ4Q2xhbXBlZEJ1ZmZlckF0dHJpYnV0ZTtcblxuXG5mdW5jdGlvbiBJbnQxNkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdEJ1ZmZlckF0dHJpYnV0ZS5jYWxsKCB0aGlzLCBuZXcgSW50MTZBcnJheSggYXJyYXkgKSwgaXRlbVNpemUgKTtcblxufVxuXG5JbnQxNkJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlICk7XG5JbnQxNkJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBJbnQxNkJ1ZmZlckF0dHJpYnV0ZTtcblxuXG5mdW5jdGlvbiBVaW50MTZCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRCdWZmZXJBdHRyaWJ1dGUuY2FsbCggdGhpcywgbmV3IFVpbnQxNkFycmF5KCBhcnJheSApLCBpdGVtU2l6ZSApO1xuXG59XG5cblVpbnQxNkJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlICk7XG5VaW50MTZCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVWludDE2QnVmZmVyQXR0cmlidXRlO1xuXG5cbmZ1bmN0aW9uIEludDMyQnVmZmVyQXR0cmlidXRlKCBhcnJheSwgaXRlbVNpemUgKSB7XG5cblx0QnVmZmVyQXR0cmlidXRlLmNhbGwoIHRoaXMsIG5ldyBJbnQzMkFycmF5KCBhcnJheSApLCBpdGVtU2l6ZSApO1xuXG59XG5cbkludDMyQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgKTtcbkludDMyQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEludDMyQnVmZmVyQXR0cmlidXRlO1xuXG5cbmZ1bmN0aW9uIFVpbnQzMkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdEJ1ZmZlckF0dHJpYnV0ZS5jYWxsKCB0aGlzLCBuZXcgVWludDMyQXJyYXkoIGFycmF5ICksIGl0ZW1TaXplICk7XG5cbn1cblxuVWludDMyQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgKTtcblVpbnQzMkJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBVaW50MzJCdWZmZXJBdHRyaWJ1dGU7XG5cblxuZnVuY3Rpb24gRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdEJ1ZmZlckF0dHJpYnV0ZS5jYWxsKCB0aGlzLCBuZXcgRmxvYXQzMkFycmF5KCBhcnJheSApLCBpdGVtU2l6ZSApO1xuXG59XG5cbkZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSApO1xuRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBGbG9hdDMyQnVmZmVyQXR0cmlidXRlO1xuXG5cbmZ1bmN0aW9uIEZsb2F0NjRCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRCdWZmZXJBdHRyaWJ1dGUuY2FsbCggdGhpcywgbmV3IEZsb2F0NjRBcnJheSggYXJyYXkgKSwgaXRlbVNpemUgKTtcblxufVxuXG5GbG9hdDY0QnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgKTtcbkZsb2F0NjRCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRmxvYXQ2NEJ1ZmZlckF0dHJpYnV0ZTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIERpcmVjdEdlb21ldHJ5KCkge1xuXG5cdHRoaXMuaW5kaWNlcyA9IFtdO1xuXHR0aGlzLnZlcnRpY2VzID0gW107XG5cdHRoaXMubm9ybWFscyA9IFtdO1xuXHR0aGlzLmNvbG9ycyA9IFtdO1xuXHR0aGlzLnV2cyA9IFtdO1xuXHR0aGlzLnV2czIgPSBbXTtcblxuXHR0aGlzLmdyb3VwcyA9IFtdO1xuXG5cdHRoaXMubW9ycGhUYXJnZXRzID0ge307XG5cblx0dGhpcy5za2luV2VpZ2h0cyA9IFtdO1xuXHR0aGlzLnNraW5JbmRpY2VzID0gW107XG5cblx0Ly8gdGhpcy5saW5lRGlzdGFuY2VzID0gW107XG5cblx0dGhpcy5ib3VuZGluZ0JveCA9IG51bGw7XG5cdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBudWxsO1xuXG5cdC8vIHVwZGF0ZSBmbGFnc1xuXG5cdHRoaXMudmVydGljZXNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMubm9ybWFsc05lZWRVcGRhdGUgPSBmYWxzZTtcblx0dGhpcy5jb2xvcnNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMudXZzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuXHR0aGlzLmdyb3Vwc05lZWRVcGRhdGUgPSBmYWxzZTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBEaXJlY3RHZW9tZXRyeS5wcm90b3R5cGUsIHtcblxuXHRjb21wdXRlR3JvdXBzOiBmdW5jdGlvbiAoIGdlb21ldHJ5ICkge1xuXG5cdFx0dmFyIGdyb3VwO1xuXHRcdHZhciBncm91cHMgPSBbXTtcblx0XHR2YXIgbWF0ZXJpYWxJbmRleCA9IHVuZGVmaW5lZDtcblxuXHRcdHZhciBmYWNlcyA9IGdlb21ldHJ5LmZhY2VzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgZmFjZXMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHR2YXIgZmFjZSA9IGZhY2VzWyBpIF07XG5cblx0XHRcdC8vIG1hdGVyaWFsc1xuXG5cdFx0XHRpZiAoIGZhY2UubWF0ZXJpYWxJbmRleCAhPT0gbWF0ZXJpYWxJbmRleCApIHtcblxuXHRcdFx0XHRtYXRlcmlhbEluZGV4ID0gZmFjZS5tYXRlcmlhbEluZGV4O1xuXG5cdFx0XHRcdGlmICggZ3JvdXAgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdGdyb3VwLmNvdW50ID0gKCBpICogMyApIC0gZ3JvdXAuc3RhcnQ7XG5cdFx0XHRcdFx0Z3JvdXBzLnB1c2goIGdyb3VwICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGdyb3VwID0ge1xuXHRcdFx0XHRcdHN0YXJ0OiBpICogMyxcblx0XHRcdFx0XHRtYXRlcmlhbEluZGV4OiBtYXRlcmlhbEluZGV4XG5cdFx0XHRcdH07XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggZ3JvdXAgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Z3JvdXAuY291bnQgPSAoIGkgKiAzICkgLSBncm91cC5zdGFydDtcblx0XHRcdGdyb3Vwcy5wdXNoKCBncm91cCApO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5ncm91cHMgPSBncm91cHM7XG5cblx0fSxcblxuXHRmcm9tR2VvbWV0cnk6IGZ1bmN0aW9uICggZ2VvbWV0cnkgKSB7XG5cblx0XHR2YXIgZmFjZXMgPSBnZW9tZXRyeS5mYWNlcztcblx0XHR2YXIgdmVydGljZXMgPSBnZW9tZXRyeS52ZXJ0aWNlcztcblx0XHR2YXIgZmFjZVZlcnRleFV2cyA9IGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnM7XG5cblx0XHR2YXIgaGFzRmFjZVZlcnRleFV2ID0gZmFjZVZlcnRleFV2c1sgMCBdICYmIGZhY2VWZXJ0ZXhVdnNbIDAgXS5sZW5ndGggPiAwO1xuXHRcdHZhciBoYXNGYWNlVmVydGV4VXYyID0gZmFjZVZlcnRleFV2c1sgMSBdICYmIGZhY2VWZXJ0ZXhVdnNbIDEgXS5sZW5ndGggPiAwO1xuXG5cdFx0Ly8gbW9ycGhzXG5cblx0XHR2YXIgbW9ycGhUYXJnZXRzID0gZ2VvbWV0cnkubW9ycGhUYXJnZXRzO1xuXHRcdHZhciBtb3JwaFRhcmdldHNMZW5ndGggPSBtb3JwaFRhcmdldHMubGVuZ3RoO1xuXG5cdFx0dmFyIG1vcnBoVGFyZ2V0c1Bvc2l0aW9uO1xuXG5cdFx0aWYgKCBtb3JwaFRhcmdldHNMZW5ndGggPiAwICkge1xuXG5cdFx0XHRtb3JwaFRhcmdldHNQb3NpdGlvbiA9IFtdO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBtb3JwaFRhcmdldHNMZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0bW9ycGhUYXJnZXRzUG9zaXRpb25bIGkgXSA9IFtdO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubW9ycGhUYXJnZXRzLnBvc2l0aW9uID0gbW9ycGhUYXJnZXRzUG9zaXRpb247XG5cblx0XHR9XG5cblx0XHR2YXIgbW9ycGhOb3JtYWxzID0gZ2VvbWV0cnkubW9ycGhOb3JtYWxzO1xuXHRcdHZhciBtb3JwaE5vcm1hbHNMZW5ndGggPSBtb3JwaE5vcm1hbHMubGVuZ3RoO1xuXG5cdFx0dmFyIG1vcnBoVGFyZ2V0c05vcm1hbDtcblxuXHRcdGlmICggbW9ycGhOb3JtYWxzTGVuZ3RoID4gMCApIHtcblxuXHRcdFx0bW9ycGhUYXJnZXRzTm9ybWFsID0gW107XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IG1vcnBoTm9ybWFsc0xlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHRtb3JwaFRhcmdldHNOb3JtYWxbIGkgXSA9IFtdO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubW9ycGhUYXJnZXRzLm5vcm1hbCA9IG1vcnBoVGFyZ2V0c05vcm1hbDtcblxuXHRcdH1cblxuXHRcdC8vIHNraW5zXG5cblx0XHR2YXIgc2tpbkluZGljZXMgPSBnZW9tZXRyeS5za2luSW5kaWNlcztcblx0XHR2YXIgc2tpbldlaWdodHMgPSBnZW9tZXRyeS5za2luV2VpZ2h0cztcblxuXHRcdHZhciBoYXNTa2luSW5kaWNlcyA9IHNraW5JbmRpY2VzLmxlbmd0aCA9PT0gdmVydGljZXMubGVuZ3RoO1xuXHRcdHZhciBoYXNTa2luV2VpZ2h0cyA9IHNraW5XZWlnaHRzLmxlbmd0aCA9PT0gdmVydGljZXMubGVuZ3RoO1xuXG5cdFx0Ly9cblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGZhY2VzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGZhY2UgPSBmYWNlc1sgaSBdO1xuXG5cdFx0XHR0aGlzLnZlcnRpY2VzLnB1c2goIHZlcnRpY2VzWyBmYWNlLmEgXSwgdmVydGljZXNbIGZhY2UuYiBdLCB2ZXJ0aWNlc1sgZmFjZS5jIF0gKTtcblxuXHRcdFx0dmFyIHZlcnRleE5vcm1hbHMgPSBmYWNlLnZlcnRleE5vcm1hbHM7XG5cblx0XHRcdGlmICggdmVydGV4Tm9ybWFscy5sZW5ndGggPT09IDMgKSB7XG5cblx0XHRcdFx0dGhpcy5ub3JtYWxzLnB1c2goIHZlcnRleE5vcm1hbHNbIDAgXSwgdmVydGV4Tm9ybWFsc1sgMSBdLCB2ZXJ0ZXhOb3JtYWxzWyAyIF0gKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHR2YXIgbm9ybWFsID0gZmFjZS5ub3JtYWw7XG5cblx0XHRcdFx0dGhpcy5ub3JtYWxzLnB1c2goIG5vcm1hbCwgbm9ybWFsLCBub3JtYWwgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgdmVydGV4Q29sb3JzID0gZmFjZS52ZXJ0ZXhDb2xvcnM7XG5cblx0XHRcdGlmICggdmVydGV4Q29sb3JzLmxlbmd0aCA9PT0gMyApIHtcblxuXHRcdFx0XHR0aGlzLmNvbG9ycy5wdXNoKCB2ZXJ0ZXhDb2xvcnNbIDAgXSwgdmVydGV4Q29sb3JzWyAxIF0sIHZlcnRleENvbG9yc1sgMiBdICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dmFyIGNvbG9yID0gZmFjZS5jb2xvcjtcblxuXHRcdFx0XHR0aGlzLmNvbG9ycy5wdXNoKCBjb2xvciwgY29sb3IsIGNvbG9yICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNGYWNlVmVydGV4VXYgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0dmFyIHZlcnRleFV2cyA9IGZhY2VWZXJ0ZXhVdnNbIDAgXVsgaSBdO1xuXG5cdFx0XHRcdGlmICggdmVydGV4VXZzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHR0aGlzLnV2cy5wdXNoKCB2ZXJ0ZXhVdnNbIDAgXSwgdmVydGV4VXZzWyAxIF0sIHZlcnRleFV2c1sgMiBdICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkRpcmVjdEdlb21ldHJ5LmZyb21HZW9tZXRyeSgpOiBVbmRlZmluZWQgdmVydGV4VXYgJywgaSApO1xuXG5cdFx0XHRcdFx0dGhpcy51dnMucHVzaCggbmV3IFZlY3RvcjIoKSwgbmV3IFZlY3RvcjIoKSwgbmV3IFZlY3RvcjIoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc0ZhY2VWZXJ0ZXhVdjIgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0dmFyIHZlcnRleFV2cyA9IGZhY2VWZXJ0ZXhVdnNbIDEgXVsgaSBdO1xuXG5cdFx0XHRcdGlmICggdmVydGV4VXZzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHR0aGlzLnV2czIucHVzaCggdmVydGV4VXZzWyAwIF0sIHZlcnRleFV2c1sgMSBdLCB2ZXJ0ZXhVdnNbIDIgXSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5EaXJlY3RHZW9tZXRyeS5mcm9tR2VvbWV0cnkoKTogVW5kZWZpbmVkIHZlcnRleFV2MiAnLCBpICk7XG5cblx0XHRcdFx0XHR0aGlzLnV2czIucHVzaCggbmV3IFZlY3RvcjIoKSwgbmV3IFZlY3RvcjIoKSwgbmV3IFZlY3RvcjIoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBtb3JwaHNcblxuXHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgbW9ycGhUYXJnZXRzTGVuZ3RoOyBqICsrICkge1xuXG5cdFx0XHRcdHZhciBtb3JwaFRhcmdldCA9IG1vcnBoVGFyZ2V0c1sgaiBdLnZlcnRpY2VzO1xuXG5cdFx0XHRcdG1vcnBoVGFyZ2V0c1Bvc2l0aW9uWyBqIF0ucHVzaCggbW9ycGhUYXJnZXRbIGZhY2UuYSBdLCBtb3JwaFRhcmdldFsgZmFjZS5iIF0sIG1vcnBoVGFyZ2V0WyBmYWNlLmMgXSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IG1vcnBoTm9ybWFsc0xlbmd0aDsgaiArKyApIHtcblxuXHRcdFx0XHR2YXIgbW9ycGhOb3JtYWwgPSBtb3JwaE5vcm1hbHNbIGogXS52ZXJ0ZXhOb3JtYWxzWyBpIF07XG5cblx0XHRcdFx0bW9ycGhUYXJnZXRzTm9ybWFsWyBqIF0ucHVzaCggbW9ycGhOb3JtYWwuYSwgbW9ycGhOb3JtYWwuYiwgbW9ycGhOb3JtYWwuYyApO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIHNraW5zXG5cblx0XHRcdGlmICggaGFzU2tpbkluZGljZXMgKSB7XG5cblx0XHRcdFx0dGhpcy5za2luSW5kaWNlcy5wdXNoKCBza2luSW5kaWNlc1sgZmFjZS5hIF0sIHNraW5JbmRpY2VzWyBmYWNlLmIgXSwgc2tpbkluZGljZXNbIGZhY2UuYyBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNTa2luV2VpZ2h0cyApIHtcblxuXHRcdFx0XHR0aGlzLnNraW5XZWlnaHRzLnB1c2goIHNraW5XZWlnaHRzWyBmYWNlLmEgXSwgc2tpbldlaWdodHNbIGZhY2UuYiBdLCBza2luV2VpZ2h0c1sgZmFjZS5jIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dGhpcy5jb21wdXRlR3JvdXBzKCBnZW9tZXRyeSApO1xuXG5cdFx0dGhpcy52ZXJ0aWNlc05lZWRVcGRhdGUgPSBnZW9tZXRyeS52ZXJ0aWNlc05lZWRVcGRhdGU7XG5cdFx0dGhpcy5ub3JtYWxzTmVlZFVwZGF0ZSA9IGdlb21ldHJ5Lm5vcm1hbHNOZWVkVXBkYXRlO1xuXHRcdHRoaXMuY29sb3JzTmVlZFVwZGF0ZSA9IGdlb21ldHJ5LmNvbG9yc05lZWRVcGRhdGU7XG5cdFx0dGhpcy51dnNOZWVkVXBkYXRlID0gZ2VvbWV0cnkudXZzTmVlZFVwZGF0ZTtcblx0XHR0aGlzLmdyb3Vwc05lZWRVcGRhdGUgPSBnZW9tZXRyeS5ncm91cHNOZWVkVXBkYXRlO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbmZ1bmN0aW9uIGFycmF5TWF4KCBhcnJheSApIHtcblxuXHRpZiAoIGFycmF5Lmxlbmd0aCA9PT0gMCApIHJldHVybiAtIEluZmluaXR5O1xuXG5cdHZhciBtYXggPSBhcnJheVsgMCBdO1xuXG5cdGZvciAoIHZhciBpID0gMSwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7ICsrIGkgKSB7XG5cblx0XHRpZiAoIGFycmF5WyBpIF0gPiBtYXggKSBtYXggPSBhcnJheVsgaSBdO1xuXG5cdH1cblxuXHRyZXR1cm4gbWF4O1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3Iga2lsZSAvIGh0dHA6Ly9raWxlLnN0cmF2YWdhbnphLm9yZy9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICovXG5cbnZhciBjb3VudCA9IDA7XG5mdW5jdGlvbiBHZW9tZXRyeUlkQ291bnQoKSB7IHJldHVybiBjb3VudCsrOyB9XG5cbmZ1bmN0aW9uIEdlb21ldHJ5KCkge1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggdGhpcywgJ2lkJywgeyB2YWx1ZTogR2VvbWV0cnlJZENvdW50KCkgfSApO1xuXG5cdHRoaXMudXVpZCA9IF9NYXRoLmdlbmVyYXRlVVVJRCgpO1xuXG5cdHRoaXMubmFtZSA9ICcnO1xuXHR0aGlzLnR5cGUgPSAnR2VvbWV0cnknO1xuXG5cdHRoaXMudmVydGljZXMgPSBbXTtcblx0dGhpcy5jb2xvcnMgPSBbXTtcblx0dGhpcy5mYWNlcyA9IFtdO1xuXHR0aGlzLmZhY2VWZXJ0ZXhVdnMgPSBbW11dO1xuXG5cdHRoaXMubW9ycGhUYXJnZXRzID0gW107XG5cdHRoaXMubW9ycGhOb3JtYWxzID0gW107XG5cblx0dGhpcy5za2luV2VpZ2h0cyA9IFtdO1xuXHR0aGlzLnNraW5JbmRpY2VzID0gW107XG5cblx0dGhpcy5saW5lRGlzdGFuY2VzID0gW107XG5cblx0dGhpcy5ib3VuZGluZ0JveCA9IG51bGw7XG5cdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBudWxsO1xuXG5cdC8vIHVwZGF0ZSBmbGFnc1xuXG5cdHRoaXMuZWxlbWVudHNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMudmVydGljZXNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMudXZzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuXHR0aGlzLm5vcm1hbHNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMuY29sb3JzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuXHR0aGlzLmxpbmVEaXN0YW5jZXNOZWVkVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMuZ3JvdXBzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEdlb21ldHJ5LnByb3RvdHlwZSwgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZSwge1xuXG5cdGlzR2VvbWV0cnk6IHRydWUsXG5cblx0YXBwbHlNYXRyaXg6IGZ1bmN0aW9uICggbWF0cml4ICkge1xuXG5cdFx0dmFyIG5vcm1hbE1hdHJpeCA9IG5ldyBNYXRyaXgzKCkuZ2V0Tm9ybWFsTWF0cml4KCBtYXRyaXggKTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSB0aGlzLnZlcnRpY2VzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgdmVydGV4ID0gdGhpcy52ZXJ0aWNlc1sgaSBdO1xuXHRcdFx0dmVydGV4LmFwcGx5TWF0cml4NCggbWF0cml4ICk7XG5cblx0XHR9XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGZhY2UgPSB0aGlzLmZhY2VzWyBpIF07XG5cdFx0XHRmYWNlLm5vcm1hbC5hcHBseU1hdHJpeDMoIG5vcm1hbE1hdHJpeCApLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDAsIGpsID0gZmFjZS52ZXJ0ZXhOb3JtYWxzLmxlbmd0aDsgaiA8IGpsOyBqICsrICkge1xuXG5cdFx0XHRcdGZhY2UudmVydGV4Tm9ybWFsc1sgaiBdLmFwcGx5TWF0cml4Myggbm9ybWFsTWF0cml4ICkubm9ybWFsaXplKCk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ib3VuZGluZ0JveCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5jb21wdXRlQm91bmRpbmdCb3goKTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ib3VuZGluZ1NwaGVyZSAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTtcblxuXHRcdH1cblxuXHRcdHRoaXMudmVydGljZXNOZWVkVXBkYXRlID0gdHJ1ZTtcblx0XHR0aGlzLm5vcm1hbHNOZWVkVXBkYXRlID0gdHJ1ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0cm90YXRlWDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB4LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWCggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblgoIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0cm90YXRlWTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB5LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWSggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblkoIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0cm90YXRlWjogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB6LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWiggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblooIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyB0cmFuc2xhdGUgZ2VvbWV0cnlcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdHJhbnNsYXRlKCB4LCB5LCB6ICkge1xuXG5cdFx0XHRtMS5tYWtlVHJhbnNsYXRpb24oIHgsIHksIHogKTtcblxuXHRcdFx0dGhpcy5hcHBseU1hdHJpeCggbTEgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRzY2FsZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gc2NhbGUgZ2VvbWV0cnlcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gc2NhbGUoIHgsIHksIHogKSB7XG5cblx0XHRcdG0xLm1ha2VTY2FsZSggeCwgeSwgeiApO1xuXG5cdFx0XHR0aGlzLmFwcGx5TWF0cml4KCBtMSApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGxvb2tBdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIG9iaiA9IG5ldyBPYmplY3QzRCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGxvb2tBdCggdmVjdG9yICkge1xuXG5cdFx0XHRvYmoubG9va0F0KCB2ZWN0b3IgKTtcblxuXHRcdFx0b2JqLnVwZGF0ZU1hdHJpeCgpO1xuXG5cdFx0XHR0aGlzLmFwcGx5TWF0cml4KCBvYmoubWF0cml4ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRmcm9tQnVmZmVyR2VvbWV0cnk6IGZ1bmN0aW9uICggZ2VvbWV0cnkgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGluZGljZXMgPSBnZW9tZXRyeS5pbmRleCAhPT0gbnVsbCA/IGdlb21ldHJ5LmluZGV4LmFycmF5IDogdW5kZWZpbmVkO1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gZ2VvbWV0cnkuYXR0cmlidXRlcztcblxuXHRcdHZhciBwb3NpdGlvbnMgPSBhdHRyaWJ1dGVzLnBvc2l0aW9uLmFycmF5O1xuXHRcdHZhciBub3JtYWxzID0gYXR0cmlidXRlcy5ub3JtYWwgIT09IHVuZGVmaW5lZCA/IGF0dHJpYnV0ZXMubm9ybWFsLmFycmF5IDogdW5kZWZpbmVkO1xuXHRcdHZhciBjb2xvcnMgPSBhdHRyaWJ1dGVzLmNvbG9yICE9PSB1bmRlZmluZWQgPyBhdHRyaWJ1dGVzLmNvbG9yLmFycmF5IDogdW5kZWZpbmVkO1xuXHRcdHZhciB1dnMgPSBhdHRyaWJ1dGVzLnV2ICE9PSB1bmRlZmluZWQgPyBhdHRyaWJ1dGVzLnV2LmFycmF5IDogdW5kZWZpbmVkO1xuXHRcdHZhciB1dnMyID0gYXR0cmlidXRlcy51djIgIT09IHVuZGVmaW5lZCA/IGF0dHJpYnV0ZXMudXYyLmFycmF5IDogdW5kZWZpbmVkO1xuXG5cdFx0aWYgKCB1dnMyICE9PSB1bmRlZmluZWQgKSB0aGlzLmZhY2VWZXJ0ZXhVdnNbIDEgXSA9IFtdO1xuXG5cdFx0dmFyIHRlbXBOb3JtYWxzID0gW107XG5cdFx0dmFyIHRlbXBVVnMgPSBbXTtcblx0XHR2YXIgdGVtcFVWczIgPSBbXTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaiA9IDA7IGkgPCBwb3NpdGlvbnMubGVuZ3RoOyBpICs9IDMsIGogKz0gMiApIHtcblxuXHRcdFx0c2NvcGUudmVydGljZXMucHVzaCggbmV3IFZlY3RvcjMoIHBvc2l0aW9uc1sgaSBdLCBwb3NpdGlvbnNbIGkgKyAxIF0sIHBvc2l0aW9uc1sgaSArIDIgXSApICk7XG5cblx0XHRcdGlmICggbm9ybWFscyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHRlbXBOb3JtYWxzLnB1c2goIG5ldyBWZWN0b3IzKCBub3JtYWxzWyBpIF0sIG5vcm1hbHNbIGkgKyAxIF0sIG5vcm1hbHNbIGkgKyAyIF0gKSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggY29sb3JzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0c2NvcGUuY29sb3JzLnB1c2goIG5ldyBDb2xvciggY29sb3JzWyBpIF0sIGNvbG9yc1sgaSArIDEgXSwgY29sb3JzWyBpICsgMiBdICkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHV2cyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHRlbXBVVnMucHVzaCggbmV3IFZlY3RvcjIoIHV2c1sgaiBdLCB1dnNbIGogKyAxIF0gKSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggdXZzMiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHRlbXBVVnMyLnB1c2goIG5ldyBWZWN0b3IyKCB1dnMyWyBqIF0sIHV2czJbIGogKyAxIF0gKSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBhZGRGYWNlKCBhLCBiLCBjLCBtYXRlcmlhbEluZGV4ICkge1xuXG5cdFx0XHR2YXIgdmVydGV4Tm9ybWFscyA9IG5vcm1hbHMgIT09IHVuZGVmaW5lZCA/IFsgdGVtcE5vcm1hbHNbIGEgXS5jbG9uZSgpLCB0ZW1wTm9ybWFsc1sgYiBdLmNsb25lKCksIHRlbXBOb3JtYWxzWyBjIF0uY2xvbmUoKSBdIDogW107XG5cdFx0XHR2YXIgdmVydGV4Q29sb3JzID0gY29sb3JzICE9PSB1bmRlZmluZWQgPyBbIHNjb3BlLmNvbG9yc1sgYSBdLmNsb25lKCksIHNjb3BlLmNvbG9yc1sgYiBdLmNsb25lKCksIHNjb3BlLmNvbG9yc1sgYyBdLmNsb25lKCkgXSA6IFtdO1xuXG5cdFx0XHR2YXIgZmFjZSA9IG5ldyBGYWNlMyggYSwgYiwgYywgdmVydGV4Tm9ybWFscywgdmVydGV4Q29sb3JzLCBtYXRlcmlhbEluZGV4ICk7XG5cblx0XHRcdHNjb3BlLmZhY2VzLnB1c2goIGZhY2UgKTtcblxuXHRcdFx0aWYgKCB1dnMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRzY29wZS5mYWNlVmVydGV4VXZzWyAwIF0ucHVzaCggWyB0ZW1wVVZzWyBhIF0uY2xvbmUoKSwgdGVtcFVWc1sgYiBdLmNsb25lKCksIHRlbXBVVnNbIGMgXS5jbG9uZSgpIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHV2czIgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRzY29wZS5mYWNlVmVydGV4VXZzWyAxIF0ucHVzaCggWyB0ZW1wVVZzMlsgYSBdLmNsb25lKCksIHRlbXBVVnMyWyBiIF0uY2xvbmUoKSwgdGVtcFVWczJbIGMgXS5jbG9uZSgpIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIGdyb3VwcyA9IGdlb21ldHJ5Lmdyb3VwcztcblxuXHRcdGlmICggZ3JvdXBzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGdyb3Vwcy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGdyb3VwID0gZ3JvdXBzWyBpIF07XG5cblx0XHRcdFx0dmFyIHN0YXJ0ID0gZ3JvdXAuc3RhcnQ7XG5cdFx0XHRcdHZhciBjb3VudCA9IGdyb3VwLmNvdW50O1xuXG5cdFx0XHRcdGZvciAoIHZhciBqID0gc3RhcnQsIGpsID0gc3RhcnQgKyBjb3VudDsgaiA8IGpsOyBqICs9IDMgKSB7XG5cblx0XHRcdFx0XHRpZiAoIGluZGljZXMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdFx0YWRkRmFjZSggaW5kaWNlc1sgaiBdLCBpbmRpY2VzWyBqICsgMSBdLCBpbmRpY2VzWyBqICsgMiBdLCBncm91cC5tYXRlcmlhbEluZGV4ICk7XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRhZGRGYWNlKCBqLCBqICsgMSwgaiArIDIsIGdyb3VwLm1hdGVyaWFsSW5kZXggKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGlmICggaW5kaWNlcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpICs9IDMgKSB7XG5cblx0XHRcdFx0XHRhZGRGYWNlKCBpbmRpY2VzWyBpIF0sIGluZGljZXNbIGkgKyAxIF0sIGluZGljZXNbIGkgKyAyIF0gKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgcG9zaXRpb25zLmxlbmd0aCAvIDM7IGkgKz0gMyApIHtcblxuXHRcdFx0XHRcdGFkZEZhY2UoIGksIGkgKyAxLCBpICsgMiApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dGhpcy5jb21wdXRlRmFjZU5vcm1hbHMoKTtcblxuXHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdCb3ggIT09IG51bGwgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdCb3ggPSBnZW9tZXRyeS5ib3VuZGluZ0JveC5jbG9uZSgpO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBnZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlLmNsb25lKCk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNlbnRlcjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5jb21wdXRlQm91bmRpbmdCb3goKTtcblxuXHRcdHZhciBvZmZzZXQgPSB0aGlzLmJvdW5kaW5nQm94LmdldENlbnRlcigpLm5lZ2F0ZSgpO1xuXG5cdFx0dGhpcy50cmFuc2xhdGUoIG9mZnNldC54LCBvZmZzZXQueSwgb2Zmc2V0LnogKTtcblxuXHRcdHJldHVybiBvZmZzZXQ7XG5cblx0fSxcblxuXHRub3JtYWxpemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk7XG5cblx0XHR2YXIgY2VudGVyID0gdGhpcy5ib3VuZGluZ1NwaGVyZS5jZW50ZXI7XG5cdFx0dmFyIHJhZGl1cyA9IHRoaXMuYm91bmRpbmdTcGhlcmUucmFkaXVzO1xuXG5cdFx0dmFyIHMgPSByYWRpdXMgPT09IDAgPyAxIDogMS4wIC8gcmFkaXVzO1xuXG5cdFx0dmFyIG1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0bWF0cml4LnNldChcblx0XHRcdHMsIDAsIDAsIC0gcyAqIGNlbnRlci54LFxuXHRcdFx0MCwgcywgMCwgLSBzICogY2VudGVyLnksXG5cdFx0XHQwLCAwLCBzLCAtIHMgKiBjZW50ZXIueixcblx0XHRcdDAsIDAsIDAsIDFcblx0XHQpO1xuXG5cdFx0dGhpcy5hcHBseU1hdHJpeCggbWF0cml4ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvbXB1dGVGYWNlTm9ybWFsczogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGNiID0gbmV3IFZlY3RvcjMoKSwgYWIgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0Zm9yICggdmFyIGYgPSAwLCBmbCA9IHRoaXMuZmFjZXMubGVuZ3RoOyBmIDwgZmw7IGYgKysgKSB7XG5cblx0XHRcdHZhciBmYWNlID0gdGhpcy5mYWNlc1sgZiBdO1xuXG5cdFx0XHR2YXIgdkEgPSB0aGlzLnZlcnRpY2VzWyBmYWNlLmEgXTtcblx0XHRcdHZhciB2QiA9IHRoaXMudmVydGljZXNbIGZhY2UuYiBdO1xuXHRcdFx0dmFyIHZDID0gdGhpcy52ZXJ0aWNlc1sgZmFjZS5jIF07XG5cblx0XHRcdGNiLnN1YlZlY3RvcnMoIHZDLCB2QiApO1xuXHRcdFx0YWIuc3ViVmVjdG9ycyggdkEsIHZCICk7XG5cdFx0XHRjYi5jcm9zcyggYWIgKTtcblxuXHRcdFx0Y2Iubm9ybWFsaXplKCk7XG5cblx0XHRcdGZhY2Uubm9ybWFsLmNvcHkoIGNiICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjb21wdXRlVmVydGV4Tm9ybWFsczogZnVuY3Rpb24gKCBhcmVhV2VpZ2h0ZWQgKSB7XG5cblx0XHRpZiAoIGFyZWFXZWlnaHRlZCA9PT0gdW5kZWZpbmVkICkgYXJlYVdlaWdodGVkID0gdHJ1ZTtcblxuXHRcdHZhciB2LCB2bCwgZiwgZmwsIGZhY2UsIHZlcnRpY2VzO1xuXG5cdFx0dmVydGljZXMgPSBuZXcgQXJyYXkoIHRoaXMudmVydGljZXMubGVuZ3RoICk7XG5cblx0XHRmb3IgKCB2ID0gMCwgdmwgPSB0aGlzLnZlcnRpY2VzLmxlbmd0aDsgdiA8IHZsOyB2ICsrICkge1xuXG5cdFx0XHR2ZXJ0aWNlc1sgdiBdID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdH1cblxuXHRcdGlmICggYXJlYVdlaWdodGVkICkge1xuXG5cdFx0XHQvLyB2ZXJ0ZXggbm9ybWFscyB3ZWlnaHRlZCBieSB0cmlhbmdsZSBhcmVhc1xuXHRcdFx0Ly8gaHR0cDovL3d3dy5pcXVpbGV6bGVzLm9yZy93d3cvYXJ0aWNsZXMvbm9ybWFscy9ub3JtYWxzLmh0bVxuXG5cdFx0XHR2YXIgdkEsIHZCLCB2Qztcblx0XHRcdHZhciBjYiA9IG5ldyBWZWN0b3IzKCksIGFiID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0Zm9yICggZiA9IDAsIGZsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGYgPCBmbDsgZiArKyApIHtcblxuXHRcdFx0XHRmYWNlID0gdGhpcy5mYWNlc1sgZiBdO1xuXG5cdFx0XHRcdHZBID0gdGhpcy52ZXJ0aWNlc1sgZmFjZS5hIF07XG5cdFx0XHRcdHZCID0gdGhpcy52ZXJ0aWNlc1sgZmFjZS5iIF07XG5cdFx0XHRcdHZDID0gdGhpcy52ZXJ0aWNlc1sgZmFjZS5jIF07XG5cblx0XHRcdFx0Y2Iuc3ViVmVjdG9ycyggdkMsIHZCICk7XG5cdFx0XHRcdGFiLnN1YlZlY3RvcnMoIHZBLCB2QiApO1xuXHRcdFx0XHRjYi5jcm9zcyggYWIgKTtcblxuXHRcdFx0XHR2ZXJ0aWNlc1sgZmFjZS5hIF0uYWRkKCBjYiApO1xuXHRcdFx0XHR2ZXJ0aWNlc1sgZmFjZS5iIF0uYWRkKCBjYiApO1xuXHRcdFx0XHR2ZXJ0aWNlc1sgZmFjZS5jIF0uYWRkKCBjYiApO1xuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHR0aGlzLmNvbXB1dGVGYWNlTm9ybWFscygpO1xuXG5cdFx0XHRmb3IgKCBmID0gMCwgZmwgPSB0aGlzLmZhY2VzLmxlbmd0aDsgZiA8IGZsOyBmICsrICkge1xuXG5cdFx0XHRcdGZhY2UgPSB0aGlzLmZhY2VzWyBmIF07XG5cblx0XHRcdFx0dmVydGljZXNbIGZhY2UuYSBdLmFkZCggZmFjZS5ub3JtYWwgKTtcblx0XHRcdFx0dmVydGljZXNbIGZhY2UuYiBdLmFkZCggZmFjZS5ub3JtYWwgKTtcblx0XHRcdFx0dmVydGljZXNbIGZhY2UuYyBdLmFkZCggZmFjZS5ub3JtYWwgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Zm9yICggdiA9IDAsIHZsID0gdGhpcy52ZXJ0aWNlcy5sZW5ndGg7IHYgPCB2bDsgdiArKyApIHtcblxuXHRcdFx0dmVydGljZXNbIHYgXS5ub3JtYWxpemUoKTtcblxuXHRcdH1cblxuXHRcdGZvciAoIGYgPSAwLCBmbCA9IHRoaXMuZmFjZXMubGVuZ3RoOyBmIDwgZmw7IGYgKysgKSB7XG5cblx0XHRcdGZhY2UgPSB0aGlzLmZhY2VzWyBmIF07XG5cblx0XHRcdHZhciB2ZXJ0ZXhOb3JtYWxzID0gZmFjZS52ZXJ0ZXhOb3JtYWxzO1xuXG5cdFx0XHRpZiAoIHZlcnRleE5vcm1hbHMubGVuZ3RoID09PSAzICkge1xuXG5cdFx0XHRcdHZlcnRleE5vcm1hbHNbIDAgXS5jb3B5KCB2ZXJ0aWNlc1sgZmFjZS5hIF0gKTtcblx0XHRcdFx0dmVydGV4Tm9ybWFsc1sgMSBdLmNvcHkoIHZlcnRpY2VzWyBmYWNlLmIgXSApO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAyIF0uY29weSggdmVydGljZXNbIGZhY2UuYyBdICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dmVydGV4Tm9ybWFsc1sgMCBdID0gdmVydGljZXNbIGZhY2UuYSBdLmNsb25lKCk7XG5cdFx0XHRcdHZlcnRleE5vcm1hbHNbIDEgXSA9IHZlcnRpY2VzWyBmYWNlLmIgXS5jbG9uZSgpO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAyIF0gPSB2ZXJ0aWNlc1sgZmFjZS5jIF0uY2xvbmUoKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmZhY2VzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdHRoaXMubm9ybWFsc05lZWRVcGRhdGUgPSB0cnVlO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Y29tcHV0ZUZsYXRWZXJ0ZXhOb3JtYWxzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgZiwgZmwsIGZhY2U7XG5cblx0XHR0aGlzLmNvbXB1dGVGYWNlTm9ybWFscygpO1xuXG5cdFx0Zm9yICggZiA9IDAsIGZsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGYgPCBmbDsgZiArKyApIHtcblxuXHRcdFx0ZmFjZSA9IHRoaXMuZmFjZXNbIGYgXTtcblxuXHRcdFx0dmFyIHZlcnRleE5vcm1hbHMgPSBmYWNlLnZlcnRleE5vcm1hbHM7XG5cblx0XHRcdGlmICggdmVydGV4Tm9ybWFscy5sZW5ndGggPT09IDMgKSB7XG5cblx0XHRcdFx0dmVydGV4Tm9ybWFsc1sgMCBdLmNvcHkoIGZhY2Uubm9ybWFsICk7XG5cdFx0XHRcdHZlcnRleE5vcm1hbHNbIDEgXS5jb3B5KCBmYWNlLm5vcm1hbCApO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAyIF0uY29weSggZmFjZS5ub3JtYWwgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAwIF0gPSBmYWNlLm5vcm1hbC5jbG9uZSgpO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAxIF0gPSBmYWNlLm5vcm1hbC5jbG9uZSgpO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzWyAyIF0gPSBmYWNlLm5vcm1hbC5jbG9uZSgpO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuZmFjZXMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dGhpcy5ub3JtYWxzTmVlZFVwZGF0ZSA9IHRydWU7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjb21wdXRlTW9ycGhOb3JtYWxzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgaSwgaWwsIGYsIGZsLCBmYWNlO1xuXG5cdFx0Ly8gc2F2ZSBvcmlnaW5hbCBub3JtYWxzXG5cdFx0Ly8gLSBjcmVhdGUgdGVtcCB2YXJpYWJsZXMgb24gZmlyc3QgYWNjZXNzXG5cdFx0Ly8gICBvdGhlcndpc2UganVzdCBjb3B5IChmb3IgZmFzdGVyIHJlcGVhdGVkIGNhbGxzKVxuXG5cdFx0Zm9yICggZiA9IDAsIGZsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGYgPCBmbDsgZiArKyApIHtcblxuXHRcdFx0ZmFjZSA9IHRoaXMuZmFjZXNbIGYgXTtcblxuXHRcdFx0aWYgKCAhIGZhY2UuX19vcmlnaW5hbEZhY2VOb3JtYWwgKSB7XG5cblx0XHRcdFx0ZmFjZS5fX29yaWdpbmFsRmFjZU5vcm1hbCA9IGZhY2Uubm9ybWFsLmNsb25lKCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0ZmFjZS5fX29yaWdpbmFsRmFjZU5vcm1hbC5jb3B5KCBmYWNlLm5vcm1hbCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggISBmYWNlLl9fb3JpZ2luYWxWZXJ0ZXhOb3JtYWxzICkgZmFjZS5fX29yaWdpbmFsVmVydGV4Tm9ybWFscyA9IFtdO1xuXG5cdFx0XHRmb3IgKCBpID0gMCwgaWwgPSBmYWNlLnZlcnRleE5vcm1hbHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0aWYgKCAhIGZhY2UuX19vcmlnaW5hbFZlcnRleE5vcm1hbHNbIGkgXSApIHtcblxuXHRcdFx0XHRcdGZhY2UuX19vcmlnaW5hbFZlcnRleE5vcm1hbHNbIGkgXSA9IGZhY2UudmVydGV4Tm9ybWFsc1sgaSBdLmNsb25lKCk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGZhY2UuX19vcmlnaW5hbFZlcnRleE5vcm1hbHNbIGkgXS5jb3B5KCBmYWNlLnZlcnRleE5vcm1hbHNbIGkgXSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gdXNlIHRlbXAgZ2VvbWV0cnkgdG8gY29tcHV0ZSBmYWNlIGFuZCB2ZXJ0ZXggbm9ybWFscyBmb3IgZWFjaCBtb3JwaFxuXG5cdFx0dmFyIHRtcEdlbyA9IG5ldyBHZW9tZXRyeSgpO1xuXHRcdHRtcEdlby5mYWNlcyA9IHRoaXMuZmFjZXM7XG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSB0aGlzLm1vcnBoVGFyZ2V0cy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0Ly8gY3JlYXRlIG9uIGZpcnN0IGFjY2Vzc1xuXG5cdFx0XHRpZiAoICEgdGhpcy5tb3JwaE5vcm1hbHNbIGkgXSApIHtcblxuXHRcdFx0XHR0aGlzLm1vcnBoTm9ybWFsc1sgaSBdID0ge307XG5cdFx0XHRcdHRoaXMubW9ycGhOb3JtYWxzWyBpIF0uZmFjZU5vcm1hbHMgPSBbXTtcblx0XHRcdFx0dGhpcy5tb3JwaE5vcm1hbHNbIGkgXS52ZXJ0ZXhOb3JtYWxzID0gW107XG5cblx0XHRcdFx0dmFyIGRzdE5vcm1hbHNGYWNlID0gdGhpcy5tb3JwaE5vcm1hbHNbIGkgXS5mYWNlTm9ybWFscztcblx0XHRcdFx0dmFyIGRzdE5vcm1hbHNWZXJ0ZXggPSB0aGlzLm1vcnBoTm9ybWFsc1sgaSBdLnZlcnRleE5vcm1hbHM7XG5cblx0XHRcdFx0dmFyIGZhY2VOb3JtYWwsIHZlcnRleE5vcm1hbHM7XG5cblx0XHRcdFx0Zm9yICggZiA9IDAsIGZsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGYgPCBmbDsgZiArKyApIHtcblxuXHRcdFx0XHRcdGZhY2VOb3JtYWwgPSBuZXcgVmVjdG9yMygpO1xuXHRcdFx0XHRcdHZlcnRleE5vcm1hbHMgPSB7IGE6IG5ldyBWZWN0b3IzKCksIGI6IG5ldyBWZWN0b3IzKCksIGM6IG5ldyBWZWN0b3IzKCkgfTtcblxuXHRcdFx0XHRcdGRzdE5vcm1hbHNGYWNlLnB1c2goIGZhY2VOb3JtYWwgKTtcblx0XHRcdFx0XHRkc3ROb3JtYWxzVmVydGV4LnB1c2goIHZlcnRleE5vcm1hbHMgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIG1vcnBoTm9ybWFscyA9IHRoaXMubW9ycGhOb3JtYWxzWyBpIF07XG5cblx0XHRcdC8vIHNldCB2ZXJ0aWNlcyB0byBtb3JwaCB0YXJnZXRcblxuXHRcdFx0dG1wR2VvLnZlcnRpY2VzID0gdGhpcy5tb3JwaFRhcmdldHNbIGkgXS52ZXJ0aWNlcztcblxuXHRcdFx0Ly8gY29tcHV0ZSBtb3JwaCBub3JtYWxzXG5cblx0XHRcdHRtcEdlby5jb21wdXRlRmFjZU5vcm1hbHMoKTtcblx0XHRcdHRtcEdlby5jb21wdXRlVmVydGV4Tm9ybWFscygpO1xuXG5cdFx0XHQvLyBzdG9yZSBtb3JwaCBub3JtYWxzXG5cblx0XHRcdHZhciBmYWNlTm9ybWFsLCB2ZXJ0ZXhOb3JtYWxzO1xuXG5cdFx0XHRmb3IgKCBmID0gMCwgZmwgPSB0aGlzLmZhY2VzLmxlbmd0aDsgZiA8IGZsOyBmICsrICkge1xuXG5cdFx0XHRcdGZhY2UgPSB0aGlzLmZhY2VzWyBmIF07XG5cblx0XHRcdFx0ZmFjZU5vcm1hbCA9IG1vcnBoTm9ybWFscy5mYWNlTm9ybWFsc1sgZiBdO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzID0gbW9ycGhOb3JtYWxzLnZlcnRleE5vcm1hbHNbIGYgXTtcblxuXHRcdFx0XHRmYWNlTm9ybWFsLmNvcHkoIGZhY2Uubm9ybWFsICk7XG5cblx0XHRcdFx0dmVydGV4Tm9ybWFscy5hLmNvcHkoIGZhY2UudmVydGV4Tm9ybWFsc1sgMCBdICk7XG5cdFx0XHRcdHZlcnRleE5vcm1hbHMuYi5jb3B5KCBmYWNlLnZlcnRleE5vcm1hbHNbIDEgXSApO1xuXHRcdFx0XHR2ZXJ0ZXhOb3JtYWxzLmMuY29weSggZmFjZS52ZXJ0ZXhOb3JtYWxzWyAyIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gcmVzdG9yZSBvcmlnaW5hbCBub3JtYWxzXG5cblx0XHRmb3IgKCBmID0gMCwgZmwgPSB0aGlzLmZhY2VzLmxlbmd0aDsgZiA8IGZsOyBmICsrICkge1xuXG5cdFx0XHRmYWNlID0gdGhpcy5mYWNlc1sgZiBdO1xuXG5cdFx0XHRmYWNlLm5vcm1hbCA9IGZhY2UuX19vcmlnaW5hbEZhY2VOb3JtYWw7XG5cdFx0XHRmYWNlLnZlcnRleE5vcm1hbHMgPSBmYWNlLl9fb3JpZ2luYWxWZXJ0ZXhOb3JtYWxzO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Y29tcHV0ZUxpbmVEaXN0YW5jZXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBkID0gMDtcblx0XHR2YXIgdmVydGljZXMgPSB0aGlzLnZlcnRpY2VzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHZlcnRpY2VzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHRpZiAoIGkgPiAwICkge1xuXG5cdFx0XHRcdGQgKz0gdmVydGljZXNbIGkgXS5kaXN0YW5jZVRvKCB2ZXJ0aWNlc1sgaSAtIDEgXSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubGluZURpc3RhbmNlc1sgaSBdID0gZDtcblxuXHRcdH1cblxuXHR9LFxuXG5cdGNvbXB1dGVCb3VuZGluZ0JveDogZnVuY3Rpb24gKCkge1xuXG5cdFx0aWYgKCB0aGlzLmJvdW5kaW5nQm94ID09PSBudWxsICkge1xuXG5cdFx0XHR0aGlzLmJvdW5kaW5nQm94ID0gbmV3IEJveDMoKTtcblxuXHRcdH1cblxuXHRcdHRoaXMuYm91bmRpbmdCb3guc2V0RnJvbVBvaW50cyggdGhpcy52ZXJ0aWNlcyApO1xuXG5cdH0sXG5cblx0Y29tcHV0ZUJvdW5kaW5nU3BoZXJlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRpZiAoIHRoaXMuYm91bmRpbmdTcGhlcmUgPT09IG51bGwgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBuZXcgU3BoZXJlKCk7XG5cblx0XHR9XG5cblx0XHR0aGlzLmJvdW5kaW5nU3BoZXJlLnNldEZyb21Qb2ludHMoIHRoaXMudmVydGljZXMgKTtcblxuXHR9LFxuXG5cdG1lcmdlOiBmdW5jdGlvbiAoIGdlb21ldHJ5LCBtYXRyaXgsIG1hdGVyaWFsSW5kZXhPZmZzZXQgKSB7XG5cblx0XHRpZiAoICggZ2VvbWV0cnkgJiYgZ2VvbWV0cnkuaXNHZW9tZXRyeSApID09PSBmYWxzZSApIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLkdlb21ldHJ5Lm1lcmdlKCk6IGdlb21ldHJ5IG5vdCBhbiBpbnN0YW5jZSBvZiBUSFJFRS5HZW9tZXRyeS4nLCBnZW9tZXRyeSApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0dmFyIG5vcm1hbE1hdHJpeCxcblx0XHRcdHZlcnRleE9mZnNldCA9IHRoaXMudmVydGljZXMubGVuZ3RoLFxuXHRcdFx0dmVydGljZXMxID0gdGhpcy52ZXJ0aWNlcyxcblx0XHRcdHZlcnRpY2VzMiA9IGdlb21ldHJ5LnZlcnRpY2VzLFxuXHRcdFx0ZmFjZXMxID0gdGhpcy5mYWNlcyxcblx0XHRcdGZhY2VzMiA9IGdlb21ldHJ5LmZhY2VzLFxuXHRcdFx0dXZzMSA9IHRoaXMuZmFjZVZlcnRleFV2c1sgMCBdLFxuXHRcdFx0dXZzMiA9IGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbIDAgXSxcblx0XHRcdGNvbG9yczEgPSB0aGlzLmNvbG9ycyxcblx0XHRcdGNvbG9yczIgPSBnZW9tZXRyeS5jb2xvcnM7XG5cblx0XHRpZiAoIG1hdGVyaWFsSW5kZXhPZmZzZXQgPT09IHVuZGVmaW5lZCApIG1hdGVyaWFsSW5kZXhPZmZzZXQgPSAwO1xuXG5cdFx0aWYgKCBtYXRyaXggIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0bm9ybWFsTWF0cml4ID0gbmV3IE1hdHJpeDMoKS5nZXROb3JtYWxNYXRyaXgoIG1hdHJpeCApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gdmVydGljZXNcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSB2ZXJ0aWNlczIubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHZhciB2ZXJ0ZXggPSB2ZXJ0aWNlczJbIGkgXTtcblxuXHRcdFx0dmFyIHZlcnRleENvcHkgPSB2ZXJ0ZXguY2xvbmUoKTtcblxuXHRcdFx0aWYgKCBtYXRyaXggIT09IHVuZGVmaW5lZCApIHZlcnRleENvcHkuYXBwbHlNYXRyaXg0KCBtYXRyaXggKTtcblxuXHRcdFx0dmVydGljZXMxLnB1c2goIHZlcnRleENvcHkgKTtcblxuXHRcdH1cblxuXHRcdC8vIGNvbG9yc1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IGNvbG9yczIubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdGNvbG9yczEucHVzaCggY29sb3JzMlsgaSBdLmNsb25lKCkgKTtcblxuXHRcdH1cblxuXHRcdC8vIGZhY2VzXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBmYWNlczIubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBmYWNlID0gZmFjZXMyWyBpIF0sIGZhY2VDb3B5LCBub3JtYWwsIGNvbG9yLFxuXHRcdFx0XHRmYWNlVmVydGV4Tm9ybWFscyA9IGZhY2UudmVydGV4Tm9ybWFscyxcblx0XHRcdFx0ZmFjZVZlcnRleENvbG9ycyA9IGZhY2UudmVydGV4Q29sb3JzO1xuXG5cdFx0XHRmYWNlQ29weSA9IG5ldyBGYWNlMyggZmFjZS5hICsgdmVydGV4T2Zmc2V0LCBmYWNlLmIgKyB2ZXJ0ZXhPZmZzZXQsIGZhY2UuYyArIHZlcnRleE9mZnNldCApO1xuXHRcdFx0ZmFjZUNvcHkubm9ybWFsLmNvcHkoIGZhY2Uubm9ybWFsICk7XG5cblx0XHRcdGlmICggbm9ybWFsTWF0cml4ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0ZmFjZUNvcHkubm9ybWFsLmFwcGx5TWF0cml4Myggbm9ybWFsTWF0cml4ICkubm9ybWFsaXplKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggdmFyIGogPSAwLCBqbCA9IGZhY2VWZXJ0ZXhOb3JtYWxzLmxlbmd0aDsgaiA8IGpsOyBqICsrICkge1xuXG5cdFx0XHRcdG5vcm1hbCA9IGZhY2VWZXJ0ZXhOb3JtYWxzWyBqIF0uY2xvbmUoKTtcblxuXHRcdFx0XHRpZiAoIG5vcm1hbE1hdHJpeCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0bm9ybWFsLmFwcGx5TWF0cml4Myggbm9ybWFsTWF0cml4ICkubm9ybWFsaXplKCk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZhY2VDb3B5LnZlcnRleE5vcm1hbHMucHVzaCggbm9ybWFsICk7XG5cblx0XHRcdH1cblxuXHRcdFx0ZmFjZUNvcHkuY29sb3IuY29weSggZmFjZS5jb2xvciApO1xuXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDAsIGpsID0gZmFjZVZlcnRleENvbG9ycy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHRjb2xvciA9IGZhY2VWZXJ0ZXhDb2xvcnNbIGogXTtcblx0XHRcdFx0ZmFjZUNvcHkudmVydGV4Q29sb3JzLnB1c2goIGNvbG9yLmNsb25lKCkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRmYWNlQ29weS5tYXRlcmlhbEluZGV4ID0gZmFjZS5tYXRlcmlhbEluZGV4ICsgbWF0ZXJpYWxJbmRleE9mZnNldDtcblxuXHRcdFx0ZmFjZXMxLnB1c2goIGZhY2VDb3B5ICk7XG5cblx0XHR9XG5cblx0XHQvLyB1dnNcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IHV2czIubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHZhciB1diA9IHV2czJbIGkgXSwgdXZDb3B5ID0gW107XG5cblx0XHRcdGlmICggdXYgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb250aW51ZTtcblxuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDAsIGpsID0gdXYubGVuZ3RoOyBqIDwgamw7IGogKysgKSB7XG5cblx0XHRcdFx0dXZDb3B5LnB1c2goIHV2WyBqIF0uY2xvbmUoKSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHV2czEucHVzaCggdXZDb3B5ICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRtZXJnZU1lc2g6IGZ1bmN0aW9uICggbWVzaCApIHtcblxuXHRcdGlmICggKCBtZXNoICYmIG1lc2guaXNNZXNoICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuR2VvbWV0cnkubWVyZ2VNZXNoKCk6IG1lc2ggbm90IGFuIGluc3RhbmNlIG9mIFRIUkVFLk1lc2guJywgbWVzaCApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0bWVzaC5tYXRyaXhBdXRvVXBkYXRlICYmIG1lc2gudXBkYXRlTWF0cml4KCk7XG5cblx0XHR0aGlzLm1lcmdlKCBtZXNoLmdlb21ldHJ5LCBtZXNoLm1hdHJpeCApO1xuXG5cdH0sXG5cblx0Lypcblx0ICogQ2hlY2tzIGZvciBkdXBsaWNhdGUgdmVydGljZXMgd2l0aCBoYXNobWFwLlxuXHQgKiBEdXBsaWNhdGVkIHZlcnRpY2VzIGFyZSByZW1vdmVkXG5cdCAqIGFuZCBmYWNlcycgdmVydGljZXMgYXJlIHVwZGF0ZWQuXG5cdCAqL1xuXG5cdG1lcmdlVmVydGljZXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB2ZXJ0aWNlc01hcCA9IHt9OyAvLyBIYXNobWFwIGZvciBsb29raW5nIHVwIHZlcnRpY2VzIGJ5IHBvc2l0aW9uIGNvb3JkaW5hdGVzIChhbmQgbWFraW5nIHN1cmUgdGhleSBhcmUgdW5pcXVlKVxuXHRcdHZhciB1bmlxdWUgPSBbXSwgY2hhbmdlcyA9IFtdO1xuXG5cdFx0dmFyIHYsIGtleTtcblx0XHR2YXIgcHJlY2lzaW9uUG9pbnRzID0gNDsgLy8gbnVtYmVyIG9mIGRlY2ltYWwgcG9pbnRzLCBlLmcuIDQgZm9yIGVwc2lsb24gb2YgMC4wMDAxXG5cdFx0dmFyIHByZWNpc2lvbiA9IE1hdGgucG93KCAxMCwgcHJlY2lzaW9uUG9pbnRzICk7XG5cdFx0dmFyIGksIGlsLCBmYWNlO1xuXHRcdHZhciBpbmRpY2VzLCBqLCBqbDtcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IHRoaXMudmVydGljZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHYgPSB0aGlzLnZlcnRpY2VzWyBpIF07XG5cdFx0XHRrZXkgPSBNYXRoLnJvdW5kKCB2LnggKiBwcmVjaXNpb24gKSArICdfJyArIE1hdGgucm91bmQoIHYueSAqIHByZWNpc2lvbiApICsgJ18nICsgTWF0aC5yb3VuZCggdi56ICogcHJlY2lzaW9uICk7XG5cblx0XHRcdGlmICggdmVydGljZXNNYXBbIGtleSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0dmVydGljZXNNYXBbIGtleSBdID0gaTtcblx0XHRcdFx0dW5pcXVlLnB1c2goIHRoaXMudmVydGljZXNbIGkgXSApO1xuXHRcdFx0XHRjaGFuZ2VzWyBpIF0gPSB1bmlxdWUubGVuZ3RoIC0gMTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvL2NvbnNvbGUubG9nKCdEdXBsaWNhdGUgdmVydGV4IGZvdW5kLiAnLCBpLCAnIGNvdWxkIGJlIHVzaW5nICcsIHZlcnRpY2VzTWFwW2tleV0pO1xuXHRcdFx0XHRjaGFuZ2VzWyBpIF0gPSBjaGFuZ2VzWyB2ZXJ0aWNlc01hcFsga2V5IF0gXTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cblx0XHQvLyBpZiBmYWNlcyBhcmUgY29tcGxldGVseSBkZWdlbmVyYXRlIGFmdGVyIG1lcmdpbmcgdmVydGljZXMsIHdlXG5cdFx0Ly8gaGF2ZSB0byByZW1vdmUgdGhlbSBmcm9tIHRoZSBnZW9tZXRyeS5cblx0XHR2YXIgZmFjZUluZGljZXNUb1JlbW92ZSA9IFtdO1xuXG5cdFx0Zm9yICggaSA9IDAsIGlsID0gdGhpcy5mYWNlcy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0ZmFjZSA9IHRoaXMuZmFjZXNbIGkgXTtcblxuXHRcdFx0ZmFjZS5hID0gY2hhbmdlc1sgZmFjZS5hIF07XG5cdFx0XHRmYWNlLmIgPSBjaGFuZ2VzWyBmYWNlLmIgXTtcblx0XHRcdGZhY2UuYyA9IGNoYW5nZXNbIGZhY2UuYyBdO1xuXG5cdFx0XHRpbmRpY2VzID0gWyBmYWNlLmEsIGZhY2UuYiwgZmFjZS5jIF07XG5cblx0XHRcdC8vIGlmIGFueSBkdXBsaWNhdGUgdmVydGljZXMgYXJlIGZvdW5kIGluIGEgRmFjZTNcblx0XHRcdC8vIHdlIGhhdmUgdG8gcmVtb3ZlIHRoZSBmYWNlIGFzIG5vdGhpbmcgY2FuIGJlIHNhdmVkXG5cdFx0XHRmb3IgKCB2YXIgbiA9IDA7IG4gPCAzOyBuICsrICkge1xuXG5cdFx0XHRcdGlmICggaW5kaWNlc1sgbiBdID09PSBpbmRpY2VzWyAoIG4gKyAxICkgJSAzIF0gKSB7XG5cblx0XHRcdFx0XHRmYWNlSW5kaWNlc1RvUmVtb3ZlLnB1c2goIGkgKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZvciAoIGkgPSBmYWNlSW5kaWNlc1RvUmVtb3ZlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtLSApIHtcblxuXHRcdFx0dmFyIGlkeCA9IGZhY2VJbmRpY2VzVG9SZW1vdmVbIGkgXTtcblxuXHRcdFx0dGhpcy5mYWNlcy5zcGxpY2UoIGlkeCwgMSApO1xuXG5cdFx0XHRmb3IgKCBqID0gMCwgamwgPSB0aGlzLmZhY2VWZXJ0ZXhVdnMubGVuZ3RoOyBqIDwgamw7IGogKysgKSB7XG5cblx0XHRcdFx0dGhpcy5mYWNlVmVydGV4VXZzWyBqIF0uc3BsaWNlKCBpZHgsIDEgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gVXNlIHVuaXF1ZSBzZXQgb2YgdmVydGljZXNcblxuXHRcdHZhciBkaWZmID0gdGhpcy52ZXJ0aWNlcy5sZW5ndGggLSB1bmlxdWUubGVuZ3RoO1xuXHRcdHRoaXMudmVydGljZXMgPSB1bmlxdWU7XG5cdFx0cmV0dXJuIGRpZmY7XG5cblx0fSxcblxuXHRzb3J0RmFjZXNCeU1hdGVyaWFsSW5kZXg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBmYWNlcyA9IHRoaXMuZmFjZXM7XG5cdFx0dmFyIGxlbmd0aCA9IGZhY2VzLmxlbmd0aDtcblxuXHRcdC8vIHRhZyBmYWNlc1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRmYWNlc1sgaSBdLl9pZCA9IGk7XG5cblx0XHR9XG5cblx0XHQvLyBzb3J0IGZhY2VzXG5cblx0XHRmdW5jdGlvbiBtYXRlcmlhbEluZGV4U29ydCggYSwgYiApIHtcblxuXHRcdFx0cmV0dXJuIGEubWF0ZXJpYWxJbmRleCAtIGIubWF0ZXJpYWxJbmRleDtcblxuXHRcdH1cblxuXHRcdGZhY2VzLnNvcnQoIG1hdGVyaWFsSW5kZXhTb3J0ICk7XG5cblx0XHQvLyBzb3J0IHV2c1xuXG5cdFx0dmFyIHV2czEgPSB0aGlzLmZhY2VWZXJ0ZXhVdnNbIDAgXTtcblx0XHR2YXIgdXZzMiA9IHRoaXMuZmFjZVZlcnRleFV2c1sgMSBdO1xuXG5cdFx0dmFyIG5ld1V2czEsIG5ld1V2czI7XG5cblx0XHRpZiAoIHV2czEgJiYgdXZzMS5sZW5ndGggPT09IGxlbmd0aCApIG5ld1V2czEgPSBbXTtcblx0XHRpZiAoIHV2czIgJiYgdXZzMi5sZW5ndGggPT09IGxlbmd0aCApIG5ld1V2czIgPSBbXTtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGlkID0gZmFjZXNbIGkgXS5faWQ7XG5cblx0XHRcdGlmICggbmV3VXZzMSApIG5ld1V2czEucHVzaCggdXZzMVsgaWQgXSApO1xuXHRcdFx0aWYgKCBuZXdVdnMyICkgbmV3VXZzMi5wdXNoKCB1dnMyWyBpZCBdICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIG5ld1V2czEgKSB0aGlzLmZhY2VWZXJ0ZXhVdnNbIDAgXSA9IG5ld1V2czE7XG5cdFx0aWYgKCBuZXdVdnMyICkgdGhpcy5mYWNlVmVydGV4VXZzWyAxIF0gPSBuZXdVdnMyO1xuXG5cdH0sXG5cblx0dG9KU09OOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgZGF0YSA9IHtcblx0XHRcdG1ldGFkYXRhOiB7XG5cdFx0XHRcdHZlcnNpb246IDQuNSxcblx0XHRcdFx0dHlwZTogJ0dlb21ldHJ5Jyxcblx0XHRcdFx0Z2VuZXJhdG9yOiAnR2VvbWV0cnkudG9KU09OJ1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHQvLyBzdGFuZGFyZCBHZW9tZXRyeSBzZXJpYWxpemF0aW9uXG5cblx0XHRkYXRhLnV1aWQgPSB0aGlzLnV1aWQ7XG5cdFx0ZGF0YS50eXBlID0gdGhpcy50eXBlO1xuXHRcdGlmICggdGhpcy5uYW1lICE9PSAnJyApIGRhdGEubmFtZSA9IHRoaXMubmFtZTtcblxuXHRcdGlmICggdGhpcy5wYXJhbWV0ZXJzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHZhciBwYXJhbWV0ZXJzID0gdGhpcy5wYXJhbWV0ZXJzO1xuXG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIHBhcmFtZXRlcnMgKSB7XG5cblx0XHRcdFx0aWYgKCBwYXJhbWV0ZXJzWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkgZGF0YVsga2V5IF0gPSBwYXJhbWV0ZXJzWyBrZXkgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblxuXHRcdH1cblxuXHRcdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy52ZXJ0aWNlcy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdHZhciB2ZXJ0ZXggPSB0aGlzLnZlcnRpY2VzWyBpIF07XG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56ICk7XG5cblx0XHR9XG5cblx0XHR2YXIgZmFjZXMgPSBbXTtcblx0XHR2YXIgbm9ybWFscyA9IFtdO1xuXHRcdHZhciBub3JtYWxzSGFzaCA9IHt9O1xuXHRcdHZhciBjb2xvcnMgPSBbXTtcblx0XHR2YXIgY29sb3JzSGFzaCA9IHt9O1xuXHRcdHZhciB1dnMgPSBbXTtcblx0XHR2YXIgdXZzSGFzaCA9IHt9O1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5mYWNlcy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdHZhciBmYWNlID0gdGhpcy5mYWNlc1sgaSBdO1xuXG5cdFx0XHR2YXIgaGFzTWF0ZXJpYWwgPSB0cnVlO1xuXHRcdFx0dmFyIGhhc0ZhY2VVdiA9IGZhbHNlOyAvLyBkZXByZWNhdGVkXG5cdFx0XHR2YXIgaGFzRmFjZVZlcnRleFV2ID0gdGhpcy5mYWNlVmVydGV4VXZzWyAwIF1bIGkgXSAhPT0gdW5kZWZpbmVkO1xuXHRcdFx0dmFyIGhhc0ZhY2VOb3JtYWwgPSBmYWNlLm5vcm1hbC5sZW5ndGgoKSA+IDA7XG5cdFx0XHR2YXIgaGFzRmFjZVZlcnRleE5vcm1hbCA9IGZhY2UudmVydGV4Tm9ybWFscy5sZW5ndGggPiAwO1xuXHRcdFx0dmFyIGhhc0ZhY2VDb2xvciA9IGZhY2UuY29sb3IuciAhPT0gMSB8fCBmYWNlLmNvbG9yLmcgIT09IDEgfHwgZmFjZS5jb2xvci5iICE9PSAxO1xuXHRcdFx0dmFyIGhhc0ZhY2VWZXJ0ZXhDb2xvciA9IGZhY2UudmVydGV4Q29sb3JzLmxlbmd0aCA+IDA7XG5cblx0XHRcdHZhciBmYWNlVHlwZSA9IDA7XG5cblx0XHRcdGZhY2VUeXBlID0gc2V0Qml0KCBmYWNlVHlwZSwgMCwgMCApOyAvLyBpc1F1YWRcblx0XHRcdGZhY2VUeXBlID0gc2V0Qml0KCBmYWNlVHlwZSwgMSwgaGFzTWF0ZXJpYWwgKTtcblx0XHRcdGZhY2VUeXBlID0gc2V0Qml0KCBmYWNlVHlwZSwgMiwgaGFzRmFjZVV2ICk7XG5cdFx0XHRmYWNlVHlwZSA9IHNldEJpdCggZmFjZVR5cGUsIDMsIGhhc0ZhY2VWZXJ0ZXhVdiApO1xuXHRcdFx0ZmFjZVR5cGUgPSBzZXRCaXQoIGZhY2VUeXBlLCA0LCBoYXNGYWNlTm9ybWFsICk7XG5cdFx0XHRmYWNlVHlwZSA9IHNldEJpdCggZmFjZVR5cGUsIDUsIGhhc0ZhY2VWZXJ0ZXhOb3JtYWwgKTtcblx0XHRcdGZhY2VUeXBlID0gc2V0Qml0KCBmYWNlVHlwZSwgNiwgaGFzRmFjZUNvbG9yICk7XG5cdFx0XHRmYWNlVHlwZSA9IHNldEJpdCggZmFjZVR5cGUsIDcsIGhhc0ZhY2VWZXJ0ZXhDb2xvciApO1xuXG5cdFx0XHRmYWNlcy5wdXNoKCBmYWNlVHlwZSApO1xuXHRcdFx0ZmFjZXMucHVzaCggZmFjZS5hLCBmYWNlLmIsIGZhY2UuYyApO1xuXHRcdFx0ZmFjZXMucHVzaCggZmFjZS5tYXRlcmlhbEluZGV4ICk7XG5cblx0XHRcdGlmICggaGFzRmFjZVZlcnRleFV2ICkge1xuXG5cdFx0XHRcdHZhciBmYWNlVmVydGV4VXZzID0gdGhpcy5mYWNlVmVydGV4VXZzWyAwIF1bIGkgXTtcblxuXHRcdFx0XHRmYWNlcy5wdXNoKFxuXHRcdFx0XHRcdGdldFV2SW5kZXgoIGZhY2VWZXJ0ZXhVdnNbIDAgXSApLFxuXHRcdFx0XHRcdGdldFV2SW5kZXgoIGZhY2VWZXJ0ZXhVdnNbIDEgXSApLFxuXHRcdFx0XHRcdGdldFV2SW5kZXgoIGZhY2VWZXJ0ZXhVdnNbIDIgXSApXG5cdFx0XHRcdCk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNGYWNlTm9ybWFsICkge1xuXG5cdFx0XHRcdGZhY2VzLnB1c2goIGdldE5vcm1hbEluZGV4KCBmYWNlLm5vcm1hbCApICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNGYWNlVmVydGV4Tm9ybWFsICkge1xuXG5cdFx0XHRcdHZhciB2ZXJ0ZXhOb3JtYWxzID0gZmFjZS52ZXJ0ZXhOb3JtYWxzO1xuXG5cdFx0XHRcdGZhY2VzLnB1c2goXG5cdFx0XHRcdFx0Z2V0Tm9ybWFsSW5kZXgoIHZlcnRleE5vcm1hbHNbIDAgXSApLFxuXHRcdFx0XHRcdGdldE5vcm1hbEluZGV4KCB2ZXJ0ZXhOb3JtYWxzWyAxIF0gKSxcblx0XHRcdFx0XHRnZXROb3JtYWxJbmRleCggdmVydGV4Tm9ybWFsc1sgMiBdIClcblx0XHRcdFx0KTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc0ZhY2VDb2xvciApIHtcblxuXHRcdFx0XHRmYWNlcy5wdXNoKCBnZXRDb2xvckluZGV4KCBmYWNlLmNvbG9yICkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc0ZhY2VWZXJ0ZXhDb2xvciApIHtcblxuXHRcdFx0XHR2YXIgdmVydGV4Q29sb3JzID0gZmFjZS52ZXJ0ZXhDb2xvcnM7XG5cblx0XHRcdFx0ZmFjZXMucHVzaChcblx0XHRcdFx0XHRnZXRDb2xvckluZGV4KCB2ZXJ0ZXhDb2xvcnNbIDAgXSApLFxuXHRcdFx0XHRcdGdldENvbG9ySW5kZXgoIHZlcnRleENvbG9yc1sgMSBdICksXG5cdFx0XHRcdFx0Z2V0Q29sb3JJbmRleCggdmVydGV4Q29sb3JzWyAyIF0gKVxuXHRcdFx0XHQpO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzZXRCaXQoIHZhbHVlLCBwb3NpdGlvbiwgZW5hYmxlZCApIHtcblxuXHRcdFx0cmV0dXJuIGVuYWJsZWQgPyB2YWx1ZSB8ICggMSA8PCBwb3NpdGlvbiApIDogdmFsdWUgJiAoIH4gKCAxIDw8IHBvc2l0aW9uICkgKTtcblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGdldE5vcm1hbEluZGV4KCBub3JtYWwgKSB7XG5cblx0XHRcdHZhciBoYXNoID0gbm9ybWFsLngudG9TdHJpbmcoKSArIG5vcm1hbC55LnRvU3RyaW5nKCkgKyBub3JtYWwuei50b1N0cmluZygpO1xuXG5cdFx0XHRpZiAoIG5vcm1hbHNIYXNoWyBoYXNoIF0gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gbm9ybWFsc0hhc2hbIGhhc2ggXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRub3JtYWxzSGFzaFsgaGFzaCBdID0gbm9ybWFscy5sZW5ndGggLyAzO1xuXHRcdFx0bm9ybWFscy5wdXNoKCBub3JtYWwueCwgbm9ybWFsLnksIG5vcm1hbC56ICk7XG5cblx0XHRcdHJldHVybiBub3JtYWxzSGFzaFsgaGFzaCBdO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gZ2V0Q29sb3JJbmRleCggY29sb3IgKSB7XG5cblx0XHRcdHZhciBoYXNoID0gY29sb3Iuci50b1N0cmluZygpICsgY29sb3IuZy50b1N0cmluZygpICsgY29sb3IuYi50b1N0cmluZygpO1xuXG5cdFx0XHRpZiAoIGNvbG9yc0hhc2hbIGhhc2ggXSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiBjb2xvcnNIYXNoWyBoYXNoIF07XG5cblx0XHRcdH1cblxuXHRcdFx0Y29sb3JzSGFzaFsgaGFzaCBdID0gY29sb3JzLmxlbmd0aDtcblx0XHRcdGNvbG9ycy5wdXNoKCBjb2xvci5nZXRIZXgoKSApO1xuXG5cdFx0XHRyZXR1cm4gY29sb3JzSGFzaFsgaGFzaCBdO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gZ2V0VXZJbmRleCggdXYgKSB7XG5cblx0XHRcdHZhciBoYXNoID0gdXYueC50b1N0cmluZygpICsgdXYueS50b1N0cmluZygpO1xuXG5cdFx0XHRpZiAoIHV2c0hhc2hbIGhhc2ggXSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiB1dnNIYXNoWyBoYXNoIF07XG5cblx0XHRcdH1cblxuXHRcdFx0dXZzSGFzaFsgaGFzaCBdID0gdXZzLmxlbmd0aCAvIDI7XG5cdFx0XHR1dnMucHVzaCggdXYueCwgdXYueSApO1xuXG5cdFx0XHRyZXR1cm4gdXZzSGFzaFsgaGFzaCBdO1xuXG5cdFx0fVxuXG5cdFx0ZGF0YS5kYXRhID0ge307XG5cblx0XHRkYXRhLmRhdGEudmVydGljZXMgPSB2ZXJ0aWNlcztcblx0XHRkYXRhLmRhdGEubm9ybWFscyA9IG5vcm1hbHM7XG5cdFx0aWYgKCBjb2xvcnMubGVuZ3RoID4gMCApIGRhdGEuZGF0YS5jb2xvcnMgPSBjb2xvcnM7XG5cdFx0aWYgKCB1dnMubGVuZ3RoID4gMCApIGRhdGEuZGF0YS51dnMgPSBbIHV2cyBdOyAvLyB0ZW1wb3JhbCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5cdFx0ZGF0YS5kYXRhLmZhY2VzID0gZmFjZXM7XG5cblx0XHRyZXR1cm4gZGF0YTtcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvKlxuXHRcdCAvLyBIYW5kbGUgcHJpbWl0aXZlc1xuXG5cdFx0IHZhciBwYXJhbWV0ZXJzID0gdGhpcy5wYXJhbWV0ZXJzO1xuXG5cdFx0IGlmICggcGFyYW1ldGVycyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0IHZhciB2YWx1ZXMgPSBbXTtcblxuXHRcdCBmb3IgKCB2YXIga2V5IGluIHBhcmFtZXRlcnMgKSB7XG5cblx0XHQgdmFsdWVzLnB1c2goIHBhcmFtZXRlcnNbIGtleSBdICk7XG5cblx0XHQgfVxuXG5cdFx0IHZhciBnZW9tZXRyeSA9IE9iamVjdC5jcmVhdGUoIHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlICk7XG5cdFx0IHRoaXMuY29uc3RydWN0b3IuYXBwbHkoIGdlb21ldHJ5LCB2YWx1ZXMgKTtcblx0XHQgcmV0dXJuIGdlb21ldHJ5O1xuXG5cdFx0IH1cblxuXHRcdCByZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KCB0aGlzICk7XG5cdFx0ICovXG5cblx0XHRyZXR1cm4gbmV3IEdlb21ldHJ5KCkuY29weSggdGhpcyApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR2YXIgaSwgaWwsIGosIGpsLCBrLCBrbDtcblxuXHRcdC8vIHJlc2V0XG5cblx0XHR0aGlzLnZlcnRpY2VzID0gW107XG5cdFx0dGhpcy5jb2xvcnMgPSBbXTtcblx0XHR0aGlzLmZhY2VzID0gW107XG5cdFx0dGhpcy5mYWNlVmVydGV4VXZzID0gW1tdXTtcblx0XHR0aGlzLm1vcnBoVGFyZ2V0cyA9IFtdO1xuXHRcdHRoaXMubW9ycGhOb3JtYWxzID0gW107XG5cdFx0dGhpcy5za2luV2VpZ2h0cyA9IFtdO1xuXHRcdHRoaXMuc2tpbkluZGljZXMgPSBbXTtcblx0XHR0aGlzLmxpbmVEaXN0YW5jZXMgPSBbXTtcblx0XHR0aGlzLmJvdW5kaW5nQm94ID0gbnVsbDtcblx0XHR0aGlzLmJvdW5kaW5nU3BoZXJlID0gbnVsbDtcblxuXHRcdC8vIG5hbWVcblxuXHRcdHRoaXMubmFtZSA9IHNvdXJjZS5uYW1lO1xuXG5cdFx0Ly8gdmVydGljZXNcblxuXHRcdHZhciB2ZXJ0aWNlcyA9IHNvdXJjZS52ZXJ0aWNlcztcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IHZlcnRpY2VzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLnZlcnRpY2VzLnB1c2goIHZlcnRpY2VzWyBpIF0uY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gY29sb3JzXG5cblx0XHR2YXIgY29sb3JzID0gc291cmNlLmNvbG9ycztcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IGNvbG9ycy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0dGhpcy5jb2xvcnMucHVzaCggY29sb3JzWyBpIF0uY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gZmFjZXNcblxuXHRcdHZhciBmYWNlcyA9IHNvdXJjZS5mYWNlcztcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IGZhY2VzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLmZhY2VzLnB1c2goIGZhY2VzWyBpIF0uY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gZmFjZSB2ZXJ0ZXggdXZzXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBzb3VyY2UuZmFjZVZlcnRleFV2cy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGZhY2VWZXJ0ZXhVdnMgPSBzb3VyY2UuZmFjZVZlcnRleFV2c1sgaSBdO1xuXG5cdFx0XHRpZiAoIHRoaXMuZmFjZVZlcnRleFV2c1sgaSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0dGhpcy5mYWNlVmVydGV4VXZzWyBpIF0gPSBbXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKCBqID0gMCwgamwgPSBmYWNlVmVydGV4VXZzLmxlbmd0aDsgaiA8IGpsOyBqICsrICkge1xuXG5cdFx0XHRcdHZhciB1dnMgPSBmYWNlVmVydGV4VXZzWyBqIF0sIHV2c0NvcHkgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBrID0gMCwga2wgPSB1dnMubGVuZ3RoOyBrIDwga2w7IGsgKysgKSB7XG5cblx0XHRcdFx0XHR2YXIgdXYgPSB1dnNbIGsgXTtcblxuXHRcdFx0XHRcdHV2c0NvcHkucHVzaCggdXYuY2xvbmUoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLmZhY2VWZXJ0ZXhVdnNbIGkgXS5wdXNoKCB1dnNDb3B5ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdC8vIG1vcnBoIHRhcmdldHNcblxuXHRcdHZhciBtb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXG5cdFx0Zm9yICggaSA9IDAsIGlsID0gbW9ycGhUYXJnZXRzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgbW9ycGhUYXJnZXQgPSB7fTtcblx0XHRcdG1vcnBoVGFyZ2V0Lm5hbWUgPSBtb3JwaFRhcmdldHNbIGkgXS5uYW1lO1xuXG5cdFx0XHQvLyB2ZXJ0aWNlc1xuXG5cdFx0XHRpZiAoIG1vcnBoVGFyZ2V0c1sgaSBdLnZlcnRpY2VzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0bW9ycGhUYXJnZXQudmVydGljZXMgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBqID0gMCwgamwgPSBtb3JwaFRhcmdldHNbIGkgXS52ZXJ0aWNlcy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHRcdG1vcnBoVGFyZ2V0LnZlcnRpY2VzLnB1c2goIG1vcnBoVGFyZ2V0c1sgaSBdLnZlcnRpY2VzWyBqIF0uY2xvbmUoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBub3JtYWxzXG5cblx0XHRcdGlmICggbW9ycGhUYXJnZXRzWyBpIF0ubm9ybWFscyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdG1vcnBoVGFyZ2V0Lm5vcm1hbHMgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBqID0gMCwgamwgPSBtb3JwaFRhcmdldHNbIGkgXS5ub3JtYWxzLmxlbmd0aDsgaiA8IGpsOyBqICsrICkge1xuXG5cdFx0XHRcdFx0bW9ycGhUYXJnZXQubm9ybWFscy5wdXNoKCBtb3JwaFRhcmdldHNbIGkgXS5ub3JtYWxzWyBqIF0uY2xvbmUoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm1vcnBoVGFyZ2V0cy5wdXNoKCBtb3JwaFRhcmdldCApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gbW9ycGggbm9ybWFsc1xuXG5cdFx0dmFyIG1vcnBoTm9ybWFscyA9IHNvdXJjZS5tb3JwaE5vcm1hbHM7XG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBtb3JwaE5vcm1hbHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBtb3JwaE5vcm1hbCA9IHt9O1xuXG5cdFx0XHQvLyB2ZXJ0ZXggbm9ybWFsc1xuXG5cdFx0XHRpZiAoIG1vcnBoTm9ybWFsc1sgaSBdLnZlcnRleE5vcm1hbHMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRtb3JwaE5vcm1hbC52ZXJ0ZXhOb3JtYWxzID0gW107XG5cblx0XHRcdFx0Zm9yICggaiA9IDAsIGpsID0gbW9ycGhOb3JtYWxzWyBpIF0udmVydGV4Tm9ybWFscy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHRcdHZhciBzcmNWZXJ0ZXhOb3JtYWwgPSBtb3JwaE5vcm1hbHNbIGkgXS52ZXJ0ZXhOb3JtYWxzWyBqIF07XG5cdFx0XHRcdFx0dmFyIGRlc3RWZXJ0ZXhOb3JtYWwgPSB7fTtcblxuXHRcdFx0XHRcdGRlc3RWZXJ0ZXhOb3JtYWwuYSA9IHNyY1ZlcnRleE5vcm1hbC5hLmNsb25lKCk7XG5cdFx0XHRcdFx0ZGVzdFZlcnRleE5vcm1hbC5iID0gc3JjVmVydGV4Tm9ybWFsLmIuY2xvbmUoKTtcblx0XHRcdFx0XHRkZXN0VmVydGV4Tm9ybWFsLmMgPSBzcmNWZXJ0ZXhOb3JtYWwuYy5jbG9uZSgpO1xuXG5cdFx0XHRcdFx0bW9ycGhOb3JtYWwudmVydGV4Tm9ybWFscy5wdXNoKCBkZXN0VmVydGV4Tm9ybWFsICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdC8vIGZhY2Ugbm9ybWFsc1xuXG5cdFx0XHRpZiAoIG1vcnBoTm9ybWFsc1sgaSBdLmZhY2VOb3JtYWxzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0bW9ycGhOb3JtYWwuZmFjZU5vcm1hbHMgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBqID0gMCwgamwgPSBtb3JwaE5vcm1hbHNbIGkgXS5mYWNlTm9ybWFscy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHRcdG1vcnBoTm9ybWFsLmZhY2VOb3JtYWxzLnB1c2goIG1vcnBoTm9ybWFsc1sgaSBdLmZhY2VOb3JtYWxzWyBqIF0uY2xvbmUoKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm1vcnBoTm9ybWFscy5wdXNoKCBtb3JwaE5vcm1hbCApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gc2tpbiB3ZWlnaHRzXG5cblx0XHR2YXIgc2tpbldlaWdodHMgPSBzb3VyY2Uuc2tpbldlaWdodHM7XG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBza2luV2VpZ2h0cy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0dGhpcy5za2luV2VpZ2h0cy5wdXNoKCBza2luV2VpZ2h0c1sgaSBdLmNsb25lKCkgKTtcblxuXHRcdH1cblxuXHRcdC8vIHNraW4gaW5kaWNlc1xuXG5cdFx0dmFyIHNraW5JbmRpY2VzID0gc291cmNlLnNraW5JbmRpY2VzO1xuXG5cdFx0Zm9yICggaSA9IDAsIGlsID0gc2tpbkluZGljZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHRoaXMuc2tpbkluZGljZXMucHVzaCggc2tpbkluZGljZXNbIGkgXS5jbG9uZSgpICk7XG5cblx0XHR9XG5cblx0XHQvLyBsaW5lIGRpc3RhbmNlc1xuXG5cdFx0dmFyIGxpbmVEaXN0YW5jZXMgPSBzb3VyY2UubGluZURpc3RhbmNlcztcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IGxpbmVEaXN0YW5jZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHRoaXMubGluZURpc3RhbmNlcy5wdXNoKCBsaW5lRGlzdGFuY2VzWyBpIF0gKTtcblxuXHRcdH1cblxuXHRcdC8vIGJvdW5kaW5nIGJveFxuXG5cdFx0dmFyIGJvdW5kaW5nQm94ID0gc291cmNlLmJvdW5kaW5nQm94O1xuXG5cdFx0aWYgKCBib3VuZGluZ0JveCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5ib3VuZGluZ0JveCA9IGJvdW5kaW5nQm94LmNsb25lKCk7XG5cblx0XHR9XG5cblx0XHQvLyBib3VuZGluZyBzcGhlcmVcblxuXHRcdHZhciBib3VuZGluZ1NwaGVyZSA9IHNvdXJjZS5ib3VuZGluZ1NwaGVyZTtcblxuXHRcdGlmICggYm91bmRpbmdTcGhlcmUgIT09IG51bGwgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBib3VuZGluZ1NwaGVyZS5jbG9uZSgpO1xuXG5cdFx0fVxuXG5cdFx0Ly8gdXBkYXRlIGZsYWdzXG5cblx0XHR0aGlzLmVsZW1lbnRzTmVlZFVwZGF0ZSA9IHNvdXJjZS5lbGVtZW50c05lZWRVcGRhdGU7XG5cdFx0dGhpcy52ZXJ0aWNlc05lZWRVcGRhdGUgPSBzb3VyY2UudmVydGljZXNOZWVkVXBkYXRlO1xuXHRcdHRoaXMudXZzTmVlZFVwZGF0ZSA9IHNvdXJjZS51dnNOZWVkVXBkYXRlO1xuXHRcdHRoaXMubm9ybWFsc05lZWRVcGRhdGUgPSBzb3VyY2Uubm9ybWFsc05lZWRVcGRhdGU7XG5cdFx0dGhpcy5jb2xvcnNOZWVkVXBkYXRlID0gc291cmNlLmNvbG9yc05lZWRVcGRhdGU7XG5cdFx0dGhpcy5saW5lRGlzdGFuY2VzTmVlZFVwZGF0ZSA9IHNvdXJjZS5saW5lRGlzdGFuY2VzTmVlZFVwZGF0ZTtcblx0XHR0aGlzLmdyb3Vwc05lZWRVcGRhdGUgPSBzb3VyY2UuZ3JvdXBzTmVlZFVwZGF0ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGlzcG9zZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5kaXNwYXRjaEV2ZW50KCB7IHR5cGU6ICdkaXNwb3NlJyB9ICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyR2VvbWV0cnkoKSB7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCAnaWQnLCB7IHZhbHVlOiBHZW9tZXRyeUlkQ291bnQoKSB9ICk7XG5cblx0dGhpcy51dWlkID0gX01hdGguZ2VuZXJhdGVVVUlEKCk7XG5cblx0dGhpcy5uYW1lID0gJyc7XG5cdHRoaXMudHlwZSA9ICdCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5pbmRleCA9IG51bGw7XG5cdHRoaXMuYXR0cmlidXRlcyA9IHt9O1xuXG5cdHRoaXMubW9ycGhBdHRyaWJ1dGVzID0ge307XG5cblx0dGhpcy5ncm91cHMgPSBbXTtcblxuXHR0aGlzLmJvdW5kaW5nQm94ID0gbnVsbDtcblx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IG51bGw7XG5cblx0dGhpcy5kcmF3UmFuZ2UgPSB7IHN0YXJ0OiAwLCBjb3VudDogSW5maW5pdHkgfTtcblxufVxuXG5CdWZmZXJHZW9tZXRyeS5NYXhJbmRleCA9IDY1NTM1O1xuXG5PYmplY3QuYXNzaWduKCBCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUsIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUsIHtcblxuXHRpc0J1ZmZlckdlb21ldHJ5OiB0cnVlLFxuXG5cdGdldEluZGV4OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5pbmRleDtcblxuXHR9LFxuXG5cdHNldEluZGV4OiBmdW5jdGlvbiAoIGluZGV4ICkge1xuXG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCBpbmRleCApICkge1xuXG5cdFx0XHR0aGlzLmluZGV4ID0gbmV3ICggYXJyYXlNYXgoIGluZGV4ICkgPiA2NTUzNSA/IFVpbnQzMkJ1ZmZlckF0dHJpYnV0ZSA6IFVpbnQxNkJ1ZmZlckF0dHJpYnV0ZSApKCBpbmRleCwgMSApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dGhpcy5pbmRleCA9IGluZGV4O1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0YWRkQXR0cmlidXRlOiBmdW5jdGlvbiAoIG5hbWUsIGF0dHJpYnV0ZSApIHtcblxuXHRcdGlmICggKCBhdHRyaWJ1dGUgJiYgYXR0cmlidXRlLmlzQnVmZmVyQXR0cmlidXRlICkgPT09IGZhbHNlICYmICggYXR0cmlidXRlICYmIGF0dHJpYnV0ZS5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmFkZEF0dHJpYnV0ZSgpIG5vdyBleHBlY3RzICggbmFtZSwgYXR0cmlidXRlICkuJyApO1xuXG5cdFx0XHR0aGlzLmFkZEF0dHJpYnV0ZSggbmFtZSwgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggYXJndW1lbnRzWyAxIF0sIGFyZ3VtZW50c1sgMiBdICkgKTtcblxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBuYW1lID09PSAnaW5kZXgnICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeS5hZGRBdHRyaWJ1dGU6IFVzZSAuc2V0SW5kZXgoKSBmb3IgaW5kZXggYXR0cmlidXRlLicgKTtcblx0XHRcdHRoaXMuc2V0SW5kZXgoIGF0dHJpYnV0ZSApO1xuXG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHR0aGlzLmF0dHJpYnV0ZXNbIG5hbWUgXSA9IGF0dHJpYnV0ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Z2V0QXR0cmlidXRlOiBmdW5jdGlvbiAoIG5hbWUgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzWyBuYW1lIF07XG5cblx0fSxcblxuXHRyZW1vdmVBdHRyaWJ1dGU6IGZ1bmN0aW9uICggbmFtZSApIHtcblxuXHRcdGRlbGV0ZSB0aGlzLmF0dHJpYnV0ZXNbIG5hbWUgXTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YWRkR3JvdXA6IGZ1bmN0aW9uICggc3RhcnQsIGNvdW50LCBtYXRlcmlhbEluZGV4ICkge1xuXG5cdFx0dGhpcy5ncm91cHMucHVzaCgge1xuXG5cdFx0XHRzdGFydDogc3RhcnQsXG5cdFx0XHRjb3VudDogY291bnQsXG5cdFx0XHRtYXRlcmlhbEluZGV4OiBtYXRlcmlhbEluZGV4ICE9PSB1bmRlZmluZWQgPyBtYXRlcmlhbEluZGV4IDogMFxuXG5cdFx0fSApO1xuXG5cdH0sXG5cblx0Y2xlYXJHcm91cHM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZ3JvdXBzID0gW107XG5cblx0fSxcblxuXHRzZXREcmF3UmFuZ2U6IGZ1bmN0aW9uICggc3RhcnQsIGNvdW50ICkge1xuXG5cdFx0dGhpcy5kcmF3UmFuZ2Uuc3RhcnQgPSBzdGFydDtcblx0XHR0aGlzLmRyYXdSYW5nZS5jb3VudCA9IGNvdW50O1xuXG5cdH0sXG5cblx0YXBwbHlNYXRyaXg6IGZ1bmN0aW9uICggbWF0cml4ICkge1xuXG5cdFx0dmFyIHBvc2l0aW9uID0gdGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uO1xuXG5cdFx0aWYgKCBwb3NpdGlvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRtYXRyaXguYXBwbHlUb0J1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb24gKTtcblx0XHRcdHBvc2l0aW9uLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdH1cblxuXHRcdHZhciBub3JtYWwgPSB0aGlzLmF0dHJpYnV0ZXMubm9ybWFsO1xuXG5cdFx0aWYgKCBub3JtYWwgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dmFyIG5vcm1hbE1hdHJpeCA9IG5ldyBNYXRyaXgzKCkuZ2V0Tm9ybWFsTWF0cml4KCBtYXRyaXggKTtcblxuXHRcdFx0bm9ybWFsTWF0cml4LmFwcGx5VG9CdWZmZXJBdHRyaWJ1dGUoIG5vcm1hbCApO1xuXHRcdFx0bm9ybWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ib3VuZGluZ0JveCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5jb21wdXRlQm91bmRpbmdCb3goKTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ib3VuZGluZ1NwaGVyZSAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0cm90YXRlWDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB4LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWCggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblgoIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0cm90YXRlWTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB5LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWSggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblkoIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0cm90YXRlWjogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gcm90YXRlIGdlb21ldHJ5IGFyb3VuZCB3b3JsZCB6LWF4aXNcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcm90YXRlWiggYW5nbGUgKSB7XG5cblx0XHRcdG0xLm1ha2VSb3RhdGlvblooIGFuZ2xlICk7XG5cblx0XHRcdHRoaXMuYXBwbHlNYXRyaXgoIG0xICk7XG5cblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyB0cmFuc2xhdGUgZ2VvbWV0cnlcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdHJhbnNsYXRlKCB4LCB5LCB6ICkge1xuXG5cdFx0XHRtMS5tYWtlVHJhbnNsYXRpb24oIHgsIHksIHogKTtcblxuXHRcdFx0dGhpcy5hcHBseU1hdHJpeCggbTEgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRzY2FsZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gc2NhbGUgZ2VvbWV0cnlcblxuXHRcdHZhciBtMSA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gc2NhbGUoIHgsIHksIHogKSB7XG5cblx0XHRcdG0xLm1ha2VTY2FsZSggeCwgeSwgeiApO1xuXG5cdFx0XHR0aGlzLmFwcGx5TWF0cml4KCBtMSApO1xuXG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGxvb2tBdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIG9iaiA9IG5ldyBPYmplY3QzRCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGxvb2tBdCggdmVjdG9yICkge1xuXG5cdFx0XHRvYmoubG9va0F0KCB2ZWN0b3IgKTtcblxuXHRcdFx0b2JqLnVwZGF0ZU1hdHJpeCgpO1xuXG5cdFx0XHR0aGlzLmFwcGx5TWF0cml4KCBvYmoubWF0cml4ICk7XG5cblx0XHR9O1xuXG5cdH0oKSxcblxuXHRjZW50ZXI6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuY29tcHV0ZUJvdW5kaW5nQm94KCk7XG5cblx0XHR2YXIgb2Zmc2V0ID0gdGhpcy5ib3VuZGluZ0JveC5nZXRDZW50ZXIoKS5uZWdhdGUoKTtcblxuXHRcdHRoaXMudHJhbnNsYXRlKCBvZmZzZXQueCwgb2Zmc2V0LnksIG9mZnNldC56ICk7XG5cblx0XHRyZXR1cm4gb2Zmc2V0O1xuXG5cdH0sXG5cblx0c2V0RnJvbU9iamVjdDogZnVuY3Rpb24gKCBvYmplY3QgKSB7XG5cblx0XHQvLyBjb25zb2xlLmxvZyggJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LnNldEZyb21PYmplY3QoKS4gQ29udmVydGluZycsIG9iamVjdCwgdGhpcyApO1xuXG5cdFx0dmFyIGdlb21ldHJ5ID0gb2JqZWN0Lmdlb21ldHJ5O1xuXG5cdFx0aWYgKCBvYmplY3QuaXNQb2ludHMgfHwgb2JqZWN0LmlzTGluZSApIHtcblxuXHRcdFx0dmFyIHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBnZW9tZXRyeS52ZXJ0aWNlcy5sZW5ndGggKiAzLCAzICk7XG5cdFx0XHR2YXIgY29sb3JzID0gbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIGdlb21ldHJ5LmNvbG9ycy5sZW5ndGggKiAzLCAzICk7XG5cblx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBwb3NpdGlvbnMuY29weVZlY3RvcjNzQXJyYXkoIGdlb21ldHJ5LnZlcnRpY2VzICkgKTtcblx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCAnY29sb3InLCBjb2xvcnMuY29weUNvbG9yc0FycmF5KCBnZW9tZXRyeS5jb2xvcnMgKSApO1xuXG5cdFx0XHRpZiAoIGdlb21ldHJ5LmxpbmVEaXN0YW5jZXMgJiYgZ2VvbWV0cnkubGluZURpc3RhbmNlcy5sZW5ndGggPT09IGdlb21ldHJ5LnZlcnRpY2VzLmxlbmd0aCApIHtcblxuXHRcdFx0XHR2YXIgbGluZURpc3RhbmNlcyA9IG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBnZW9tZXRyeS5saW5lRGlzdGFuY2VzLmxlbmd0aCwgMSApO1xuXG5cdFx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCAnbGluZURpc3RhbmNlJywgbGluZURpc3RhbmNlcy5jb3B5QXJyYXkoIGdlb21ldHJ5LmxpbmVEaXN0YW5jZXMgKSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUgIT09IG51bGwgKSB7XG5cblx0XHRcdFx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlLmNsb25lKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5ib3VuZGluZ0JveCAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHR0aGlzLmJvdW5kaW5nQm94ID0gZ2VvbWV0cnkuYm91bmRpbmdCb3guY2xvbmUoKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggb2JqZWN0LmlzTWVzaCApIHtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeSAmJiBnZW9tZXRyeS5pc0dlb21ldHJ5ICkge1xuXG5cdFx0XHRcdHRoaXMuZnJvbUdlb21ldHJ5KCBnZW9tZXRyeSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHVwZGF0ZUZyb21PYmplY3Q6IGZ1bmN0aW9uICggb2JqZWN0ICkge1xuXG5cdFx0dmFyIGdlb21ldHJ5ID0gb2JqZWN0Lmdlb21ldHJ5O1xuXG5cdFx0aWYgKCBvYmplY3QuaXNNZXNoICkge1xuXG5cdFx0XHR2YXIgZGlyZWN0ID0gZ2VvbWV0cnkuX19kaXJlY3RHZW9tZXRyeTtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5lbGVtZW50c05lZWRVcGRhdGUgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0ZGlyZWN0ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRnZW9tZXRyeS5lbGVtZW50c05lZWRVcGRhdGUgPSBmYWxzZTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGRpcmVjdCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiB0aGlzLmZyb21HZW9tZXRyeSggZ2VvbWV0cnkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRkaXJlY3QudmVydGljZXNOZWVkVXBkYXRlID0gZ2VvbWV0cnkudmVydGljZXNOZWVkVXBkYXRlO1xuXHRcdFx0ZGlyZWN0Lm5vcm1hbHNOZWVkVXBkYXRlID0gZ2VvbWV0cnkubm9ybWFsc05lZWRVcGRhdGU7XG5cdFx0XHRkaXJlY3QuY29sb3JzTmVlZFVwZGF0ZSA9IGdlb21ldHJ5LmNvbG9yc05lZWRVcGRhdGU7XG5cdFx0XHRkaXJlY3QudXZzTmVlZFVwZGF0ZSA9IGdlb21ldHJ5LnV2c05lZWRVcGRhdGU7XG5cdFx0XHRkaXJlY3QuZ3JvdXBzTmVlZFVwZGF0ZSA9IGdlb21ldHJ5Lmdyb3Vwc05lZWRVcGRhdGU7XG5cblx0XHRcdGdlb21ldHJ5LnZlcnRpY2VzTmVlZFVwZGF0ZSA9IGZhbHNlO1xuXHRcdFx0Z2VvbWV0cnkubm9ybWFsc05lZWRVcGRhdGUgPSBmYWxzZTtcblx0XHRcdGdlb21ldHJ5LmNvbG9yc05lZWRVcGRhdGUgPSBmYWxzZTtcblx0XHRcdGdlb21ldHJ5LnV2c05lZWRVcGRhdGUgPSBmYWxzZTtcblx0XHRcdGdlb21ldHJ5Lmdyb3Vwc05lZWRVcGRhdGUgPSBmYWxzZTtcblxuXHRcdFx0Z2VvbWV0cnkgPSBkaXJlY3Q7XG5cblx0XHR9XG5cblx0XHR2YXIgYXR0cmlidXRlO1xuXG5cdFx0aWYgKCBnZW9tZXRyeS52ZXJ0aWNlc05lZWRVcGRhdGUgPT09IHRydWUgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlcy5wb3NpdGlvbjtcblxuXHRcdFx0aWYgKCBhdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRhdHRyaWJ1dGUuY29weVZlY3RvcjNzQXJyYXkoIGdlb21ldHJ5LnZlcnRpY2VzICk7XG5cdFx0XHRcdGF0dHJpYnV0ZS5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHRcdH1cblxuXHRcdFx0Z2VvbWV0cnkudmVydGljZXNOZWVkVXBkYXRlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5Lm5vcm1hbHNOZWVkVXBkYXRlID09PSB0cnVlICkge1xuXG5cdFx0XHRhdHRyaWJ1dGUgPSB0aGlzLmF0dHJpYnV0ZXMubm9ybWFsO1xuXG5cdFx0XHRpZiAoIGF0dHJpYnV0ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGF0dHJpYnV0ZS5jb3B5VmVjdG9yM3NBcnJheSggZ2VvbWV0cnkubm9ybWFscyApO1xuXHRcdFx0XHRhdHRyaWJ1dGUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdGdlb21ldHJ5Lm5vcm1hbHNOZWVkVXBkYXRlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5LmNvbG9yc05lZWRVcGRhdGUgPT09IHRydWUgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlcy5jb2xvcjtcblxuXHRcdFx0aWYgKCBhdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRhdHRyaWJ1dGUuY29weUNvbG9yc0FycmF5KCBnZW9tZXRyeS5jb2xvcnMgKTtcblx0XHRcdFx0YXR0cmlidXRlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0XHRnZW9tZXRyeS5jb2xvcnNOZWVkVXBkYXRlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5LnV2c05lZWRVcGRhdGUgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlcy51djtcblxuXHRcdFx0aWYgKCBhdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRhdHRyaWJ1dGUuY29weVZlY3RvcjJzQXJyYXkoIGdlb21ldHJ5LnV2cyApO1xuXHRcdFx0XHRhdHRyaWJ1dGUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdGdlb21ldHJ5LnV2c05lZWRVcGRhdGUgPSBmYWxzZTtcblxuXHRcdH1cblxuXHRcdGlmICggZ2VvbWV0cnkubGluZURpc3RhbmNlc05lZWRVcGRhdGUgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlcy5saW5lRGlzdGFuY2U7XG5cblx0XHRcdGlmICggYXR0cmlidXRlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0YXR0cmlidXRlLmNvcHlBcnJheSggZ2VvbWV0cnkubGluZURpc3RhbmNlcyApO1xuXHRcdFx0XHRhdHRyaWJ1dGUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdGdlb21ldHJ5LmxpbmVEaXN0YW5jZXNOZWVkVXBkYXRlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5Lmdyb3Vwc05lZWRVcGRhdGUgKSB7XG5cblx0XHRcdGdlb21ldHJ5LmNvbXB1dGVHcm91cHMoIG9iamVjdC5nZW9tZXRyeSApO1xuXHRcdFx0dGhpcy5ncm91cHMgPSBnZW9tZXRyeS5ncm91cHM7XG5cblx0XHRcdGdlb21ldHJ5Lmdyb3Vwc05lZWRVcGRhdGUgPSBmYWxzZTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZnJvbUdlb21ldHJ5OiBmdW5jdGlvbiAoIGdlb21ldHJ5ICkge1xuXG5cdFx0Z2VvbWV0cnkuX19kaXJlY3RHZW9tZXRyeSA9IG5ldyBEaXJlY3RHZW9tZXRyeSgpLmZyb21HZW9tZXRyeSggZ2VvbWV0cnkgKTtcblxuXHRcdHJldHVybiB0aGlzLmZyb21EaXJlY3RHZW9tZXRyeSggZ2VvbWV0cnkuX19kaXJlY3RHZW9tZXRyeSApO1xuXG5cdH0sXG5cblx0ZnJvbURpcmVjdEdlb21ldHJ5OiBmdW5jdGlvbiAoIGdlb21ldHJ5ICkge1xuXG5cdFx0dmFyIHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkoIGdlb21ldHJ5LnZlcnRpY2VzLmxlbmd0aCAqIDMgKTtcblx0XHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb25zLCAzICkuY29weVZlY3RvcjNzQXJyYXkoIGdlb21ldHJ5LnZlcnRpY2VzICkgKTtcblxuXHRcdGlmICggZ2VvbWV0cnkubm9ybWFscy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHR2YXIgbm9ybWFscyA9IG5ldyBGbG9hdDMyQXJyYXkoIGdlb21ldHJ5Lm5vcm1hbHMubGVuZ3RoICogMyApO1xuXHRcdFx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgQnVmZmVyQXR0cmlidXRlKCBub3JtYWxzLCAzICkuY29weVZlY3RvcjNzQXJyYXkoIGdlb21ldHJ5Lm5vcm1hbHMgKSApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBnZW9tZXRyeS5jb2xvcnMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dmFyIGNvbG9ycyA9IG5ldyBGbG9hdDMyQXJyYXkoIGdlb21ldHJ5LmNvbG9ycy5sZW5ndGggKiAzICk7XG5cdFx0XHR0aGlzLmFkZEF0dHJpYnV0ZSggJ2NvbG9yJywgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggY29sb3JzLCAzICkuY29weUNvbG9yc0FycmF5KCBnZW9tZXRyeS5jb2xvcnMgKSApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBnZW9tZXRyeS51dnMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dmFyIHV2cyA9IG5ldyBGbG9hdDMyQXJyYXkoIGdlb21ldHJ5LnV2cy5sZW5ndGggKiAyICk7XG5cdFx0XHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkuY29weVZlY3RvcjJzQXJyYXkoIGdlb21ldHJ5LnV2cyApICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5LnV2czIubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dmFyIHV2czIgPSBuZXcgRmxvYXQzMkFycmF5KCBnZW9tZXRyeS51dnMyLmxlbmd0aCAqIDIgKTtcblx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCAndXYyJywgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggdXZzMiwgMiApLmNvcHlWZWN0b3Iyc0FycmF5KCBnZW9tZXRyeS51dnMyICkgKTtcblxuXHRcdH1cblxuXHRcdGlmICggZ2VvbWV0cnkuaW5kaWNlcy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHR2YXIgVHlwZUFycmF5ID0gYXJyYXlNYXgoIGdlb21ldHJ5LmluZGljZXMgKSA+IDY1NTM1ID8gVWludDMyQXJyYXkgOiBVaW50MTZBcnJheTtcblx0XHRcdHZhciBpbmRpY2VzID0gbmV3IFR5cGVBcnJheSggZ2VvbWV0cnkuaW5kaWNlcy5sZW5ndGggKiAzICk7XG5cdFx0XHR0aGlzLnNldEluZGV4KCBuZXcgQnVmZmVyQXR0cmlidXRlKCBpbmRpY2VzLCAxICkuY29weUluZGljZXNBcnJheSggZ2VvbWV0cnkuaW5kaWNlcyApICk7XG5cblx0XHR9XG5cblx0XHQvLyBncm91cHNcblxuXHRcdHRoaXMuZ3JvdXBzID0gZ2VvbWV0cnkuZ3JvdXBzO1xuXG5cdFx0Ly8gbW9ycGhzXG5cblx0XHRmb3IgKCB2YXIgbmFtZSBpbiBnZW9tZXRyeS5tb3JwaFRhcmdldHMgKSB7XG5cblx0XHRcdHZhciBhcnJheSA9IFtdO1xuXHRcdFx0dmFyIG1vcnBoVGFyZ2V0cyA9IGdlb21ldHJ5Lm1vcnBoVGFyZ2V0c1sgbmFtZSBdO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBtb3JwaFRhcmdldHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHR2YXIgbW9ycGhUYXJnZXQgPSBtb3JwaFRhcmdldHNbIGkgXTtcblxuXHRcdFx0XHR2YXIgYXR0cmlidXRlID0gbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG1vcnBoVGFyZ2V0Lmxlbmd0aCAqIDMsIDMgKTtcblxuXHRcdFx0XHRhcnJheS5wdXNoKCBhdHRyaWJ1dGUuY29weVZlY3RvcjNzQXJyYXkoIG1vcnBoVGFyZ2V0ICkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm1vcnBoQXR0cmlidXRlc1sgbmFtZSBdID0gYXJyYXk7XG5cblx0XHR9XG5cblx0XHQvLyBza2lubmluZ1xuXG5cdFx0aWYgKCBnZW9tZXRyeS5za2luSW5kaWNlcy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHR2YXIgc2tpbkluZGljZXMgPSBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggZ2VvbWV0cnkuc2tpbkluZGljZXMubGVuZ3RoICogNCwgNCApO1xuXHRcdFx0dGhpcy5hZGRBdHRyaWJ1dGUoICdza2luSW5kZXgnLCBza2luSW5kaWNlcy5jb3B5VmVjdG9yNHNBcnJheSggZ2VvbWV0cnkuc2tpbkluZGljZXMgKSApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBnZW9tZXRyeS5za2luV2VpZ2h0cy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHR2YXIgc2tpbldlaWdodHMgPSBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggZ2VvbWV0cnkuc2tpbldlaWdodHMubGVuZ3RoICogNCwgNCApO1xuXHRcdFx0dGhpcy5hZGRBdHRyaWJ1dGUoICdza2luV2VpZ2h0Jywgc2tpbldlaWdodHMuY29weVZlY3RvcjRzQXJyYXkoIGdlb21ldHJ5LnNraW5XZWlnaHRzICkgKTtcblxuXHRcdH1cblxuXHRcdC8vXG5cblx0XHRpZiAoIGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlICE9PSBudWxsICkge1xuXG5cdFx0XHR0aGlzLmJvdW5kaW5nU3BoZXJlID0gZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUuY2xvbmUoKTtcblxuXHRcdH1cblxuXHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdCb3ggIT09IG51bGwgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdCb3ggPSBnZW9tZXRyeS5ib3VuZGluZ0JveC5jbG9uZSgpO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjb21wdXRlQm91bmRpbmdCb3g6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGlmICggdGhpcy5ib3VuZGluZ0JveCA9PT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5ib3VuZGluZ0JveCA9IG5ldyBCb3gzKCk7XG5cblx0XHR9XG5cblx0XHR2YXIgcG9zaXRpb24gPSB0aGlzLmF0dHJpYnV0ZXMucG9zaXRpb247XG5cblx0XHRpZiAoIHBvc2l0aW9uICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdCb3guc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb24gKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdCb3gubWFrZUVtcHR5KCk7XG5cblx0XHR9XG5cblx0XHRpZiAoIGlzTmFOKCB0aGlzLmJvdW5kaW5nQm94Lm1pbi54ICkgfHwgaXNOYU4oIHRoaXMuYm91bmRpbmdCb3gubWluLnkgKSB8fCBpc05hTiggdGhpcy5ib3VuZGluZ0JveC5taW4ueiApICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuQnVmZmVyR2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94OiBDb21wdXRlZCBtaW4vbWF4IGhhdmUgTmFOIHZhbHVlcy4gVGhlIFwicG9zaXRpb25cIiBhdHRyaWJ1dGUgaXMgbGlrZWx5IHRvIGhhdmUgTmFOIHZhbHVlcy4nLCB0aGlzICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjb21wdXRlQm91bmRpbmdTcGhlcmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBib3ggPSBuZXcgQm94MygpO1xuXHRcdHZhciB2ZWN0b3IgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIGNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpIHtcblxuXHRcdFx0aWYgKCB0aGlzLmJvdW5kaW5nU3BoZXJlID09PSBudWxsICkge1xuXG5cdFx0XHRcdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBuZXcgU3BoZXJlKCk7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIHBvc2l0aW9uID0gdGhpcy5hdHRyaWJ1dGVzLnBvc2l0aW9uO1xuXG5cdFx0XHRpZiAoIHBvc2l0aW9uICkge1xuXG5cdFx0XHRcdHZhciBjZW50ZXIgPSB0aGlzLmJvdW5kaW5nU3BoZXJlLmNlbnRlcjtcblxuXHRcdFx0XHRib3guc2V0RnJvbUJ1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb24gKTtcblx0XHRcdFx0Ym94LmdldENlbnRlciggY2VudGVyICk7XG5cblx0XHRcdFx0Ly8gaG9waW5nIHRvIGZpbmQgYSBib3VuZGluZ1NwaGVyZSB3aXRoIGEgcmFkaXVzIHNtYWxsZXIgdGhhbiB0aGVcblx0XHRcdFx0Ly8gYm91bmRpbmdTcGhlcmUgb2YgdGhlIGJvdW5kaW5nQm94OiBzcXJ0KDMpIHNtYWxsZXIgaW4gdGhlIGJlc3QgY2FzZVxuXG5cdFx0XHRcdHZhciBtYXhSYWRpdXNTcSA9IDA7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHBvc2l0aW9uLmNvdW50OyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHR2ZWN0b3IueCA9IHBvc2l0aW9uLmdldFgoIGkgKTtcblx0XHRcdFx0XHR2ZWN0b3IueSA9IHBvc2l0aW9uLmdldFkoIGkgKTtcblx0XHRcdFx0XHR2ZWN0b3IueiA9IHBvc2l0aW9uLmdldFooIGkgKTtcblx0XHRcdFx0XHRtYXhSYWRpdXNTcSA9IE1hdGgubWF4KCBtYXhSYWRpdXNTcSwgY2VudGVyLmRpc3RhbmNlVG9TcXVhcmVkKCB2ZWN0b3IgKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cyA9IE1hdGguc3FydCggbWF4UmFkaXVzU3EgKTtcblxuXHRcdFx0XHRpZiAoIGlzTmFOKCB0aGlzLmJvdW5kaW5nU3BoZXJlLnJhZGl1cyApICkge1xuXG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpOiBDb21wdXRlZCByYWRpdXMgaXMgTmFOLiBUaGUgXCJwb3NpdGlvblwiIGF0dHJpYnV0ZSBpcyBsaWtlbHkgdG8gaGF2ZSBOYU4gdmFsdWVzLicsIHRoaXMgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fSgpLFxuXG5cdGNvbXB1dGVGYWNlTm9ybWFsczogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcblxuXHR9LFxuXG5cdGNvbXB1dGVWZXJ0ZXhOb3JtYWxzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgaW5kZXggPSB0aGlzLmluZGV4O1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzO1xuXHRcdHZhciBncm91cHMgPSB0aGlzLmdyb3VwcztcblxuXHRcdGlmICggYXR0cmlidXRlcy5wb3NpdGlvbiApIHtcblxuXHRcdFx0dmFyIHBvc2l0aW9ucyA9IGF0dHJpYnV0ZXMucG9zaXRpb24uYXJyYXk7XG5cblx0XHRcdGlmICggYXR0cmlidXRlcy5ub3JtYWwgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHR0aGlzLmFkZEF0dHJpYnV0ZSggJ25vcm1hbCcsIG5ldyBCdWZmZXJBdHRyaWJ1dGUoIG5ldyBGbG9hdDMyQXJyYXkoIHBvc2l0aW9ucy5sZW5ndGggKSwgMyApICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gcmVzZXQgZXhpc3Rpbmcgbm9ybWFscyB0byB6ZXJvXG5cblx0XHRcdFx0dmFyIGFycmF5ID0gYXR0cmlidXRlcy5ub3JtYWwuYXJyYXk7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHRcdFx0YXJyYXlbIGkgXSA9IDA7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBub3JtYWxzID0gYXR0cmlidXRlcy5ub3JtYWwuYXJyYXk7XG5cblx0XHRcdHZhciB2QSwgdkIsIHZDO1xuXHRcdFx0dmFyIHBBID0gbmV3IFZlY3RvcjMoKSwgcEIgPSBuZXcgVmVjdG9yMygpLCBwQyA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0XHR2YXIgY2IgPSBuZXcgVmVjdG9yMygpLCBhYiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRcdC8vIGluZGV4ZWQgZWxlbWVudHNcblxuXHRcdFx0aWYgKCBpbmRleCApIHtcblxuXHRcdFx0XHR2YXIgaW5kaWNlcyA9IGluZGV4LmFycmF5O1xuXG5cdFx0XHRcdGlmICggZ3JvdXBzLmxlbmd0aCA9PT0gMCApIHtcblxuXHRcdFx0XHRcdHRoaXMuYWRkR3JvdXAoIDAsIGluZGljZXMubGVuZ3RoICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMCwgamwgPSBncm91cHMubGVuZ3RoOyBqIDwgamw7ICsrIGogKSB7XG5cblx0XHRcdFx0XHR2YXIgZ3JvdXAgPSBncm91cHNbIGogXTtcblxuXHRcdFx0XHRcdHZhciBzdGFydCA9IGdyb3VwLnN0YXJ0O1xuXHRcdFx0XHRcdHZhciBjb3VudCA9IGdyb3VwLmNvdW50O1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGkgPSBzdGFydCwgaWwgPSBzdGFydCArIGNvdW50OyBpIDwgaWw7IGkgKz0gMyApIHtcblxuXHRcdFx0XHRcdFx0dkEgPSBpbmRpY2VzWyBpICsgMCBdICogMztcblx0XHRcdFx0XHRcdHZCID0gaW5kaWNlc1sgaSArIDEgXSAqIDM7XG5cdFx0XHRcdFx0XHR2QyA9IGluZGljZXNbIGkgKyAyIF0gKiAzO1xuXG5cdFx0XHRcdFx0XHRwQS5mcm9tQXJyYXkoIHBvc2l0aW9ucywgdkEgKTtcblx0XHRcdFx0XHRcdHBCLmZyb21BcnJheSggcG9zaXRpb25zLCB2QiApO1xuXHRcdFx0XHRcdFx0cEMuZnJvbUFycmF5KCBwb3NpdGlvbnMsIHZDICk7XG5cblx0XHRcdFx0XHRcdGNiLnN1YlZlY3RvcnMoIHBDLCBwQiApO1xuXHRcdFx0XHRcdFx0YWIuc3ViVmVjdG9ycyggcEEsIHBCICk7XG5cdFx0XHRcdFx0XHRjYi5jcm9zcyggYWIgKTtcblxuXHRcdFx0XHRcdFx0bm9ybWFsc1sgdkEgXSArPSBjYi54O1xuXHRcdFx0XHRcdFx0bm9ybWFsc1sgdkEgKyAxIF0gKz0gY2IueTtcblx0XHRcdFx0XHRcdG5vcm1hbHNbIHZBICsgMiBdICs9IGNiLno7XG5cblx0XHRcdFx0XHRcdG5vcm1hbHNbIHZCIF0gKz0gY2IueDtcblx0XHRcdFx0XHRcdG5vcm1hbHNbIHZCICsgMSBdICs9IGNiLnk7XG5cdFx0XHRcdFx0XHRub3JtYWxzWyB2QiArIDIgXSArPSBjYi56O1xuXG5cdFx0XHRcdFx0XHRub3JtYWxzWyB2QyBdICs9IGNiLng7XG5cdFx0XHRcdFx0XHRub3JtYWxzWyB2QyArIDEgXSArPSBjYi55O1xuXHRcdFx0XHRcdFx0bm9ybWFsc1sgdkMgKyAyIF0gKz0gY2IuejtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gbm9uLWluZGV4ZWQgZWxlbWVudHMgKHVuY29ubmVjdGVkIHRyaWFuZ2xlIHNvdXApXG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHBvc2l0aW9ucy5sZW5ndGg7IGkgPCBpbDsgaSArPSA5ICkge1xuXG5cdFx0XHRcdFx0cEEuZnJvbUFycmF5KCBwb3NpdGlvbnMsIGkgKTtcblx0XHRcdFx0XHRwQi5mcm9tQXJyYXkoIHBvc2l0aW9ucywgaSArIDMgKTtcblx0XHRcdFx0XHRwQy5mcm9tQXJyYXkoIHBvc2l0aW9ucywgaSArIDYgKTtcblxuXHRcdFx0XHRcdGNiLnN1YlZlY3RvcnMoIHBDLCBwQiApO1xuXHRcdFx0XHRcdGFiLnN1YlZlY3RvcnMoIHBBLCBwQiApO1xuXHRcdFx0XHRcdGNiLmNyb3NzKCBhYiApO1xuXG5cdFx0XHRcdFx0bm9ybWFsc1sgaSBdID0gY2IueDtcblx0XHRcdFx0XHRub3JtYWxzWyBpICsgMSBdID0gY2IueTtcblx0XHRcdFx0XHRub3JtYWxzWyBpICsgMiBdID0gY2IuejtcblxuXHRcdFx0XHRcdG5vcm1hbHNbIGkgKyAzIF0gPSBjYi54O1xuXHRcdFx0XHRcdG5vcm1hbHNbIGkgKyA0IF0gPSBjYi55O1xuXHRcdFx0XHRcdG5vcm1hbHNbIGkgKyA1IF0gPSBjYi56O1xuXG5cdFx0XHRcdFx0bm9ybWFsc1sgaSArIDYgXSA9IGNiLng7XG5cdFx0XHRcdFx0bm9ybWFsc1sgaSArIDcgXSA9IGNiLnk7XG5cdFx0XHRcdFx0bm9ybWFsc1sgaSArIDggXSA9IGNiLno7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubm9ybWFsaXplTm9ybWFscygpO1xuXG5cdFx0XHRhdHRyaWJ1dGVzLm5vcm1hbC5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHR9XG5cblx0fSxcblxuXHRtZXJnZTogZnVuY3Rpb24gKCBnZW9tZXRyeSwgb2Zmc2V0ICkge1xuXG5cdFx0aWYgKCAoIGdlb21ldHJ5ICYmIGdlb21ldHJ5LmlzQnVmZmVyR2VvbWV0cnkgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5CdWZmZXJHZW9tZXRyeS5tZXJnZSgpOiBnZW9tZXRyeSBub3QgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuQnVmZmVyR2VvbWV0cnkuJywgZ2VvbWV0cnkgKTtcblx0XHRcdHJldHVybjtcblxuXHRcdH1cblxuXHRcdGlmICggb2Zmc2V0ID09PSB1bmRlZmluZWQgKSBvZmZzZXQgPSAwO1xuXG5cdFx0dmFyIGF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXM7XG5cblx0XHRmb3IgKCB2YXIga2V5IGluIGF0dHJpYnV0ZXMgKSB7XG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYXR0cmlidXRlc1sga2V5IF0gPT09IHVuZGVmaW5lZCApIGNvbnRpbnVlO1xuXG5cdFx0XHR2YXIgYXR0cmlidXRlMSA9IGF0dHJpYnV0ZXNbIGtleSBdO1xuXHRcdFx0dmFyIGF0dHJpYnV0ZUFycmF5MSA9IGF0dHJpYnV0ZTEuYXJyYXk7XG5cblx0XHRcdHZhciBhdHRyaWJ1dGUyID0gZ2VvbWV0cnkuYXR0cmlidXRlc1sga2V5IF07XG5cdFx0XHR2YXIgYXR0cmlidXRlQXJyYXkyID0gYXR0cmlidXRlMi5hcnJheTtcblxuXHRcdFx0dmFyIGF0dHJpYnV0ZVNpemUgPSBhdHRyaWJ1dGUyLml0ZW1TaXplO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGogPSBhdHRyaWJ1dGVTaXplICogb2Zmc2V0OyBpIDwgYXR0cmlidXRlQXJyYXkyLmxlbmd0aDsgaSArKywgaiArKyApIHtcblxuXHRcdFx0XHRhdHRyaWJ1dGVBcnJheTFbIGogXSA9IGF0dHJpYnV0ZUFycmF5MlsgaSBdO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdG5vcm1hbGl6ZU5vcm1hbHM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBub3JtYWxzID0gdGhpcy5hdHRyaWJ1dGVzLm5vcm1hbDtcblxuXHRcdHZhciB4LCB5LCB6LCBuO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IG5vcm1hbHMuY291bnQ7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0eCA9IG5vcm1hbHMuZ2V0WCggaSApO1xuXHRcdFx0eSA9IG5vcm1hbHMuZ2V0WSggaSApO1xuXHRcdFx0eiA9IG5vcm1hbHMuZ2V0WiggaSApO1xuXG5cdFx0XHRuID0gMS4wIC8gTWF0aC5zcXJ0KCB4ICogeCArIHkgKiB5ICsgeiAqIHogKTtcblxuXHRcdFx0bm9ybWFscy5zZXRYWVooIGksIHggKiBuLCB5ICogbiwgeiAqIG4gKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdHRvTm9uSW5kZXhlZDogZnVuY3Rpb24gKCkge1xuXG5cdFx0aWYgKCB0aGlzLmluZGV4ID09PSBudWxsICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeS50b05vbkluZGV4ZWQoKTogR2VvbWV0cnkgaXMgYWxyZWFkeSBub24taW5kZXhlZC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdH1cblxuXHRcdHZhciBnZW9tZXRyeTIgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKTtcblxuXHRcdHZhciBpbmRpY2VzID0gdGhpcy5pbmRleC5hcnJheTtcblx0XHR2YXIgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcztcblxuXHRcdGZvciAoIHZhciBuYW1lIGluIGF0dHJpYnV0ZXMgKSB7XG5cblx0XHRcdHZhciBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGVzWyBuYW1lIF07XG5cblx0XHRcdHZhciBhcnJheSA9IGF0dHJpYnV0ZS5hcnJheTtcblx0XHRcdHZhciBpdGVtU2l6ZSA9IGF0dHJpYnV0ZS5pdGVtU2l6ZTtcblxuXHRcdFx0dmFyIGFycmF5MiA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvciggaW5kaWNlcy5sZW5ndGggKiBpdGVtU2l6ZSApO1xuXG5cdFx0XHR2YXIgaW5kZXggPSAwLCBpbmRleDIgPSAwO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBpbmRpY2VzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0aW5kZXggPSBpbmRpY2VzWyBpIF0gKiBpdGVtU2l6ZTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCBpdGVtU2l6ZTsgaiArKyApIHtcblxuXHRcdFx0XHRcdGFycmF5MlsgaW5kZXgyICsrIF0gPSBhcnJheVsgaW5kZXggKysgXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0Z2VvbWV0cnkyLmFkZEF0dHJpYnV0ZSggbmFtZSwgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggYXJyYXkyLCBpdGVtU2l6ZSApICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gZ2VvbWV0cnkyO1xuXG5cdH0sXG5cblx0dG9KU09OOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgZGF0YSA9IHtcblx0XHRcdG1ldGFkYXRhOiB7XG5cdFx0XHRcdHZlcnNpb246IDQuNSxcblx0XHRcdFx0dHlwZTogJ0J1ZmZlckdlb21ldHJ5Jyxcblx0XHRcdFx0Z2VuZXJhdG9yOiAnQnVmZmVyR2VvbWV0cnkudG9KU09OJ1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHQvLyBzdGFuZGFyZCBCdWZmZXJHZW9tZXRyeSBzZXJpYWxpemF0aW9uXG5cblx0XHRkYXRhLnV1aWQgPSB0aGlzLnV1aWQ7XG5cdFx0ZGF0YS50eXBlID0gdGhpcy50eXBlO1xuXHRcdGlmICggdGhpcy5uYW1lICE9PSAnJyApIGRhdGEubmFtZSA9IHRoaXMubmFtZTtcblxuXHRcdGlmICggdGhpcy5wYXJhbWV0ZXJzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHZhciBwYXJhbWV0ZXJzID0gdGhpcy5wYXJhbWV0ZXJzO1xuXG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIHBhcmFtZXRlcnMgKSB7XG5cblx0XHRcdFx0aWYgKCBwYXJhbWV0ZXJzWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkgZGF0YVsga2V5IF0gPSBwYXJhbWV0ZXJzWyBrZXkgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblxuXHRcdH1cblxuXHRcdGRhdGEuZGF0YSA9IHsgYXR0cmlidXRlczoge30gfTtcblxuXHRcdHZhciBpbmRleCA9IHRoaXMuaW5kZXg7XG5cblx0XHRpZiAoIGluZGV4ICE9PSBudWxsICkge1xuXG5cdFx0XHR2YXIgYXJyYXkgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggaW5kZXguYXJyYXkgKTtcblxuXHRcdFx0ZGF0YS5kYXRhLmluZGV4ID0ge1xuXHRcdFx0XHR0eXBlOiBpbmRleC5hcnJheS5jb25zdHJ1Y3Rvci5uYW1lLFxuXHRcdFx0XHRhcnJheTogYXJyYXlcblx0XHRcdH07XG5cblx0XHR9XG5cblx0XHR2YXIgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcztcblxuXHRcdGZvciAoIHZhciBrZXkgaW4gYXR0cmlidXRlcyApIHtcblxuXHRcdFx0dmFyIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXNbIGtleSBdO1xuXG5cdFx0XHR2YXIgYXJyYXkgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggYXR0cmlidXRlLmFycmF5ICk7XG5cblx0XHRcdGRhdGEuZGF0YS5hdHRyaWJ1dGVzWyBrZXkgXSA9IHtcblx0XHRcdFx0aXRlbVNpemU6IGF0dHJpYnV0ZS5pdGVtU2l6ZSxcblx0XHRcdFx0dHlwZTogYXR0cmlidXRlLmFycmF5LmNvbnN0cnVjdG9yLm5hbWUsXG5cdFx0XHRcdGFycmF5OiBhcnJheSxcblx0XHRcdFx0bm9ybWFsaXplZDogYXR0cmlidXRlLm5vcm1hbGl6ZWRcblx0XHRcdH07XG5cblx0XHR9XG5cblx0XHR2YXIgZ3JvdXBzID0gdGhpcy5ncm91cHM7XG5cblx0XHRpZiAoIGdyb3Vwcy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHRkYXRhLmRhdGEuZ3JvdXBzID0gSlNPTi5wYXJzZSggSlNPTi5zdHJpbmdpZnkoIGdyb3VwcyApICk7XG5cblx0XHR9XG5cblx0XHR2YXIgYm91bmRpbmdTcGhlcmUgPSB0aGlzLmJvdW5kaW5nU3BoZXJlO1xuXG5cdFx0aWYgKCBib3VuZGluZ1NwaGVyZSAhPT0gbnVsbCApIHtcblxuXHRcdFx0ZGF0YS5kYXRhLmJvdW5kaW5nU3BoZXJlID0ge1xuXHRcdFx0XHRjZW50ZXI6IGJvdW5kaW5nU3BoZXJlLmNlbnRlci50b0FycmF5KCksXG5cdFx0XHRcdHJhZGl1czogYm91bmRpbmdTcGhlcmUucmFkaXVzXG5cdFx0XHR9O1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRhdGE7XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Lypcblx0XHQgLy8gSGFuZGxlIHByaW1pdGl2ZXNcblxuXHRcdCB2YXIgcGFyYW1ldGVycyA9IHRoaXMucGFyYW1ldGVycztcblxuXHRcdCBpZiAoIHBhcmFtZXRlcnMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdCB2YXIgdmFsdWVzID0gW107XG5cblx0XHQgZm9yICggdmFyIGtleSBpbiBwYXJhbWV0ZXJzICkge1xuXG5cdFx0IHZhbHVlcy5wdXNoKCBwYXJhbWV0ZXJzWyBrZXkgXSApO1xuXG5cdFx0IH1cblxuXHRcdCB2YXIgZ2VvbWV0cnkgPSBPYmplY3QuY3JlYXRlKCB0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZSApO1xuXHRcdCB0aGlzLmNvbnN0cnVjdG9yLmFwcGx5KCBnZW9tZXRyeSwgdmFsdWVzICk7XG5cdFx0IHJldHVybiBnZW9tZXRyeTtcblxuXHRcdCB9XG5cblx0XHQgcmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSggdGhpcyApO1xuXHRcdCAqL1xuXG5cdFx0cmV0dXJuIG5ldyBCdWZmZXJHZW9tZXRyeSgpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0dmFyIG5hbWUsIGksIGw7XG5cblx0XHQvLyByZXNldFxuXG5cdFx0dGhpcy5pbmRleCA9IG51bGw7XG5cdFx0dGhpcy5hdHRyaWJ1dGVzID0ge307XG5cdFx0dGhpcy5tb3JwaEF0dHJpYnV0ZXMgPSB7fTtcblx0XHR0aGlzLmdyb3VwcyA9IFtdO1xuXHRcdHRoaXMuYm91bmRpbmdCb3ggPSBudWxsO1xuXHRcdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBudWxsO1xuXG5cdFx0Ly8gbmFtZVxuXG5cdFx0dGhpcy5uYW1lID0gc291cmNlLm5hbWU7XG5cblx0XHQvLyBpbmRleFxuXG5cdFx0dmFyIGluZGV4ID0gc291cmNlLmluZGV4O1xuXG5cdFx0aWYgKCBpbmRleCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5zZXRJbmRleCggaW5kZXguY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gYXR0cmlidXRlc1xuXG5cdFx0dmFyIGF0dHJpYnV0ZXMgPSBzb3VyY2UuYXR0cmlidXRlcztcblxuXHRcdGZvciAoIG5hbWUgaW4gYXR0cmlidXRlcyApIHtcblxuXHRcdFx0dmFyIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXNbIG5hbWUgXTtcblx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCBuYW1lLCBhdHRyaWJ1dGUuY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gbW9ycGggYXR0cmlidXRlc1xuXG5cdFx0dmFyIG1vcnBoQXR0cmlidXRlcyA9IHNvdXJjZS5tb3JwaEF0dHJpYnV0ZXM7XG5cblx0XHRmb3IgKCBuYW1lIGluIG1vcnBoQXR0cmlidXRlcyApIHtcblxuXHRcdFx0dmFyIGFycmF5ID0gW107XG5cdFx0XHR2YXIgbW9ycGhBdHRyaWJ1dGUgPSBtb3JwaEF0dHJpYnV0ZXNbIG5hbWUgXTsgLy8gbW9ycGhBdHRyaWJ1dGU6IGFycmF5IG9mIEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGVzXG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gbW9ycGhBdHRyaWJ1dGUubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRhcnJheS5wdXNoKCBtb3JwaEF0dHJpYnV0ZVsgaSBdLmNsb25lKCkgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm1vcnBoQXR0cmlidXRlc1sgbmFtZSBdID0gYXJyYXk7XG5cblx0XHR9XG5cblx0XHQvLyBncm91cHNcblxuXHRcdHZhciBncm91cHMgPSBzb3VyY2UuZ3JvdXBzO1xuXG5cdFx0Zm9yICggaSA9IDAsIGwgPSBncm91cHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGdyb3VwID0gZ3JvdXBzWyBpIF07XG5cdFx0XHR0aGlzLmFkZEdyb3VwKCBncm91cC5zdGFydCwgZ3JvdXAuY291bnQsIGdyb3VwLm1hdGVyaWFsSW5kZXggKTtcblxuXHRcdH1cblxuXHRcdC8vIGJvdW5kaW5nIGJveFxuXG5cdFx0dmFyIGJvdW5kaW5nQm94ID0gc291cmNlLmJvdW5kaW5nQm94O1xuXG5cdFx0aWYgKCBib3VuZGluZ0JveCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5ib3VuZGluZ0JveCA9IGJvdW5kaW5nQm94LmNsb25lKCk7XG5cblx0XHR9XG5cblx0XHQvLyBib3VuZGluZyBzcGhlcmVcblxuXHRcdHZhciBib3VuZGluZ1NwaGVyZSA9IHNvdXJjZS5ib3VuZGluZ1NwaGVyZTtcblxuXHRcdGlmICggYm91bmRpbmdTcGhlcmUgIT09IG51bGwgKSB7XG5cblx0XHRcdHRoaXMuYm91bmRpbmdTcGhlcmUgPSBib3VuZGluZ1NwaGVyZS5jbG9uZSgpO1xuXG5cdFx0fVxuXG5cdFx0Ly8gZHJhdyByYW5nZVxuXG5cdFx0dGhpcy5kcmF3UmFuZ2Uuc3RhcnQgPSBzb3VyY2UuZHJhd1JhbmdlLnN0YXJ0O1xuXHRcdHRoaXMuZHJhd1JhbmdlLmNvdW50ID0gc291cmNlLmRyYXdSYW5nZS5jb3VudDtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGlzcG9zZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5kaXNwYXRjaEV2ZW50KCB7IHR5cGU6ICdkaXNwb3NlJyB9ICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBqb25vYnIxIC8gaHR0cDovL2pvbm9icjEuY29tL1xuICovXG5cbmZ1bmN0aW9uIE1lc2goIGdlb21ldHJ5LCBtYXRlcmlhbCApIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ01lc2gnO1xuXG5cdHRoaXMuZ2VvbWV0cnkgPSBnZW9tZXRyeSAhPT0gdW5kZWZpbmVkID8gZ2VvbWV0cnkgOiBuZXcgQnVmZmVyR2VvbWV0cnkoKTtcblx0dGhpcy5tYXRlcmlhbCA9IG1hdGVyaWFsICE9PSB1bmRlZmluZWQgPyBtYXRlcmlhbCA6IG5ldyBNZXNoQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogTWF0aC5yYW5kb20oKSAqIDB4ZmZmZmZmIH0gKTtcblxuXHR0aGlzLmRyYXdNb2RlID0gVHJpYW5nbGVzRHJhd01vZGU7XG5cblx0dGhpcy51cGRhdGVNb3JwaFRhcmdldHMoKTtcblxufVxuXG5NZXNoLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IE1lc2gsXG5cblx0aXNNZXNoOiB0cnVlLFxuXG5cdHNldERyYXdNb2RlOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy5kcmF3TW9kZSA9IHZhbHVlO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHRPYmplY3QzRC5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHRcdHRoaXMuZHJhd01vZGUgPSBzb3VyY2UuZHJhd01vZGU7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHVwZGF0ZU1vcnBoVGFyZ2V0czogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIG1vcnBoVGFyZ2V0cyA9IHRoaXMuZ2VvbWV0cnkubW9ycGhUYXJnZXRzO1xuXG5cdFx0aWYgKCBtb3JwaFRhcmdldHMgIT09IHVuZGVmaW5lZCAmJiBtb3JwaFRhcmdldHMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXMgPSBbXTtcblx0XHRcdHRoaXMubW9ycGhUYXJnZXREaWN0aW9uYXJ5ID0ge307XG5cblx0XHRcdGZvciAoIHZhciBtID0gMCwgbWwgPSBtb3JwaFRhcmdldHMubGVuZ3RoOyBtIDwgbWw7IG0gKysgKSB7XG5cblx0XHRcdFx0dGhpcy5tb3JwaFRhcmdldEluZmx1ZW5jZXMucHVzaCggMCApO1xuXHRcdFx0XHR0aGlzLm1vcnBoVGFyZ2V0RGljdGlvbmFyeVsgbW9ycGhUYXJnZXRzWyBtIF0ubmFtZSBdID0gbTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0cmF5Y2FzdDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgaW52ZXJzZU1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0dmFyIHJheSA9IG5ldyBSYXkoKTtcblx0XHR2YXIgc3BoZXJlID0gbmV3IFNwaGVyZSgpO1xuXG5cdFx0dmFyIHZBID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgdkIgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB2QyA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHR2YXIgdGVtcEEgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB0ZW1wQiA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIHRlbXBDID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHZhciB1dkEgPSBuZXcgVmVjdG9yMigpO1xuXHRcdHZhciB1dkIgPSBuZXcgVmVjdG9yMigpO1xuXHRcdHZhciB1dkMgPSBuZXcgVmVjdG9yMigpO1xuXG5cdFx0dmFyIGJhcnljb29yZCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHR2YXIgaW50ZXJzZWN0aW9uUG9pbnQgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBpbnRlcnNlY3Rpb25Qb2ludFdvcmxkID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdGZ1bmN0aW9uIHV2SW50ZXJzZWN0aW9uKCBwb2ludCwgcDEsIHAyLCBwMywgdXYxLCB1djIsIHV2MyApIHtcblxuXHRcdFx0VHJpYW5nbGUuYmFyeWNvb3JkRnJvbVBvaW50KCBwb2ludCwgcDEsIHAyLCBwMywgYmFyeWNvb3JkICk7XG5cblx0XHRcdHV2MS5tdWx0aXBseVNjYWxhciggYmFyeWNvb3JkLnggKTtcblx0XHRcdHV2Mi5tdWx0aXBseVNjYWxhciggYmFyeWNvb3JkLnkgKTtcblx0XHRcdHV2My5tdWx0aXBseVNjYWxhciggYmFyeWNvb3JkLnogKTtcblxuXHRcdFx0dXYxLmFkZCggdXYyICkuYWRkKCB1djMgKTtcblxuXHRcdFx0cmV0dXJuIHV2MS5jbG9uZSgpO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gY2hlY2tJbnRlcnNlY3Rpb24oIG9iamVjdCwgcmF5Y2FzdGVyLCByYXksIHBBLCBwQiwgcEMsIHBvaW50ICkge1xuXG5cdFx0XHR2YXIgaW50ZXJzZWN0O1xuXHRcdFx0dmFyIG1hdGVyaWFsID0gb2JqZWN0Lm1hdGVyaWFsO1xuXG5cdFx0XHRpZiAoIG1hdGVyaWFsLnNpZGUgPT09IEJhY2tTaWRlICkge1xuXG5cdFx0XHRcdGludGVyc2VjdCA9IHJheS5pbnRlcnNlY3RUcmlhbmdsZSggcEMsIHBCLCBwQSwgdHJ1ZSwgcG9pbnQgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRpbnRlcnNlY3QgPSByYXkuaW50ZXJzZWN0VHJpYW5nbGUoIHBBLCBwQiwgcEMsIG1hdGVyaWFsLnNpZGUgIT09IERvdWJsZVNpZGUsIHBvaW50ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBpbnRlcnNlY3QgPT09IG51bGwgKSByZXR1cm4gbnVsbDtcblxuXHRcdFx0aW50ZXJzZWN0aW9uUG9pbnRXb3JsZC5jb3B5KCBwb2ludCApO1xuXHRcdFx0aW50ZXJzZWN0aW9uUG9pbnRXb3JsZC5hcHBseU1hdHJpeDQoIG9iamVjdC5tYXRyaXhXb3JsZCApO1xuXG5cdFx0XHR2YXIgZGlzdGFuY2UgPSByYXljYXN0ZXIucmF5Lm9yaWdpbi5kaXN0YW5jZVRvKCBpbnRlcnNlY3Rpb25Qb2ludFdvcmxkICk7XG5cblx0XHRcdGlmICggZGlzdGFuY2UgPCByYXljYXN0ZXIubmVhciB8fCBkaXN0YW5jZSA+IHJheWNhc3Rlci5mYXIgKSByZXR1cm4gbnVsbDtcblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZGlzdGFuY2U6IGRpc3RhbmNlLFxuXHRcdFx0XHRwb2ludDogaW50ZXJzZWN0aW9uUG9pbnRXb3JsZC5jbG9uZSgpLFxuXHRcdFx0XHRvYmplY3Q6IG9iamVjdFxuXHRcdFx0fTtcblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGNoZWNrQnVmZmVyR2VvbWV0cnlJbnRlcnNlY3Rpb24oIG9iamVjdCwgcmF5Y2FzdGVyLCByYXksIHBvc2l0aW9uLCB1diwgYSwgYiwgYyApIHtcblxuXHRcdFx0dkEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb24sIGEgKTtcblx0XHRcdHZCLmZyb21CdWZmZXJBdHRyaWJ1dGUoIHBvc2l0aW9uLCBiICk7XG5cdFx0XHR2Qy5mcm9tQnVmZmVyQXR0cmlidXRlKCBwb3NpdGlvbiwgYyApO1xuXG5cdFx0XHR2YXIgaW50ZXJzZWN0aW9uID0gY2hlY2tJbnRlcnNlY3Rpb24oIG9iamVjdCwgcmF5Y2FzdGVyLCByYXksIHZBLCB2QiwgdkMsIGludGVyc2VjdGlvblBvaW50ICk7XG5cblx0XHRcdGlmICggaW50ZXJzZWN0aW9uICkge1xuXG5cdFx0XHRcdGlmICggdXYgKSB7XG5cblx0XHRcdFx0XHR1dkEuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggdXYsIGEgKTtcblx0XHRcdFx0XHR1dkIuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggdXYsIGIgKTtcblx0XHRcdFx0XHR1dkMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggdXYsIGMgKTtcblxuXHRcdFx0XHRcdGludGVyc2VjdGlvbi51diA9IHV2SW50ZXJzZWN0aW9uKCBpbnRlcnNlY3Rpb25Qb2ludCwgdkEsIHZCLCB2QywgdXZBLCB1dkIsIHV2QyApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpbnRlcnNlY3Rpb24uZmFjZSA9IG5ldyBGYWNlMyggYSwgYiwgYywgVHJpYW5nbGUubm9ybWFsKCB2QSwgdkIsIHZDICkgKTtcblx0XHRcdFx0aW50ZXJzZWN0aW9uLmZhY2VJbmRleCA9IGE7XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGludGVyc2VjdGlvbjtcblxuXHRcdH1cblxuXHRcdHJldHVybiBmdW5jdGlvbiByYXljYXN0KCByYXljYXN0ZXIsIGludGVyc2VjdHMgKSB7XG5cblx0XHRcdHZhciBnZW9tZXRyeSA9IHRoaXMuZ2VvbWV0cnk7XG5cdFx0XHR2YXIgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsO1xuXHRcdFx0dmFyIG1hdHJpeFdvcmxkID0gdGhpcy5tYXRyaXhXb3JsZDtcblxuXHRcdFx0aWYgKCBtYXRlcmlhbCA9PT0gdW5kZWZpbmVkICkgcmV0dXJuO1xuXG5cdFx0XHQvLyBDaGVja2luZyBib3VuZGluZ1NwaGVyZSBkaXN0YW5jZSB0byByYXlcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSA9PT0gbnVsbCApIGdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpO1xuXG5cdFx0XHRzcGhlcmUuY29weSggZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUgKTtcblx0XHRcdHNwaGVyZS5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cblx0XHRcdGlmICggcmF5Y2FzdGVyLnJheS5pbnRlcnNlY3RzU3BoZXJlKCBzcGhlcmUgKSA9PT0gZmFsc2UgKSByZXR1cm47XG5cblx0XHRcdC8vXG5cblx0XHRcdGludmVyc2VNYXRyaXguZ2V0SW52ZXJzZSggbWF0cml4V29ybGQgKTtcblx0XHRcdHJheS5jb3B5KCByYXljYXN0ZXIucmF5ICkuYXBwbHlNYXRyaXg0KCBpbnZlcnNlTWF0cml4ICk7XG5cblx0XHRcdC8vIENoZWNrIGJvdW5kaW5nQm94IGJlZm9yZSBjb250aW51aW5nXG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdCb3ggIT09IG51bGwgKSB7XG5cblx0XHRcdFx0aWYgKCByYXkuaW50ZXJzZWN0c0JveCggZ2VvbWV0cnkuYm91bmRpbmdCb3ggKSA9PT0gZmFsc2UgKSByZXR1cm47XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIGludGVyc2VjdGlvbjtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5pc0J1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHRcdHZhciBhLCBiLCBjO1xuXHRcdFx0XHR2YXIgaW5kZXggPSBnZW9tZXRyeS5pbmRleDtcblx0XHRcdFx0dmFyIHBvc2l0aW9uID0gZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbjtcblx0XHRcdFx0dmFyIHV2ID0gZ2VvbWV0cnkuYXR0cmlidXRlcy51djtcblx0XHRcdFx0dmFyIGksIGw7XG5cblx0XHRcdFx0aWYgKCBpbmRleCAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHRcdC8vIGluZGV4ZWQgYnVmZmVyIGdlb21ldHJ5XG5cblx0XHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IGluZGV4LmNvdW50OyBpIDwgbDsgaSArPSAzICkge1xuXG5cdFx0XHRcdFx0XHRhID0gaW5kZXguZ2V0WCggaSApO1xuXHRcdFx0XHRcdFx0YiA9IGluZGV4LmdldFgoIGkgKyAxICk7XG5cdFx0XHRcdFx0XHRjID0gaW5kZXguZ2V0WCggaSArIDIgKTtcblxuXHRcdFx0XHRcdFx0aW50ZXJzZWN0aW9uID0gY2hlY2tCdWZmZXJHZW9tZXRyeUludGVyc2VjdGlvbiggdGhpcywgcmF5Y2FzdGVyLCByYXksIHBvc2l0aW9uLCB1diwgYSwgYiwgYyApO1xuXG5cdFx0XHRcdFx0XHRpZiAoIGludGVyc2VjdGlvbiApIHtcblxuXHRcdFx0XHRcdFx0XHRpbnRlcnNlY3Rpb24uZmFjZUluZGV4ID0gTWF0aC5mbG9vciggaSAvIDMgKTsgLy8gdHJpYW5nbGUgbnVtYmVyIGluIGluZGljZXMgYnVmZmVyIHNlbWFudGljc1xuXHRcdFx0XHRcdFx0XHRpbnRlcnNlY3RzLnB1c2goIGludGVyc2VjdGlvbiApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdC8vIG5vbi1pbmRleGVkIGJ1ZmZlciBnZW9tZXRyeVxuXG5cdFx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBwb3NpdGlvbi5jb3VudDsgaSA8IGw7IGkgKz0gMyApIHtcblxuXHRcdFx0XHRcdFx0YSA9IGk7XG5cdFx0XHRcdFx0XHRiID0gaSArIDE7XG5cdFx0XHRcdFx0XHRjID0gaSArIDI7XG5cblx0XHRcdFx0XHRcdGludGVyc2VjdGlvbiA9IGNoZWNrQnVmZmVyR2VvbWV0cnlJbnRlcnNlY3Rpb24oIHRoaXMsIHJheWNhc3RlciwgcmF5LCBwb3NpdGlvbiwgdXYsIGEsIGIsIGMgKTtcblxuXHRcdFx0XHRcdFx0aWYgKCBpbnRlcnNlY3Rpb24gKSB7XG5cblx0XHRcdFx0XHRcdFx0aW50ZXJzZWN0aW9uLmluZGV4ID0gYTsgLy8gdHJpYW5nbGUgbnVtYmVyIGluIHBvc2l0aW9ucyBidWZmZXIgc2VtYW50aWNzXG5cdFx0XHRcdFx0XHRcdGludGVyc2VjdHMucHVzaCggaW50ZXJzZWN0aW9uICk7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAoIGdlb21ldHJ5LmlzR2VvbWV0cnkgKSB7XG5cblx0XHRcdFx0dmFyIGZ2QSwgZnZCLCBmdkM7XG5cdFx0XHRcdHZhciBpc011bHRpTWF0ZXJpYWwgPSBBcnJheS5pc0FycmF5KCBtYXRlcmlhbCApO1xuXG5cdFx0XHRcdHZhciB2ZXJ0aWNlcyA9IGdlb21ldHJ5LnZlcnRpY2VzO1xuXHRcdFx0XHR2YXIgZmFjZXMgPSBnZW9tZXRyeS5mYWNlcztcblx0XHRcdFx0dmFyIHV2cztcblxuXHRcdFx0XHR2YXIgZmFjZVZlcnRleFV2cyA9IGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbIDAgXTtcblx0XHRcdFx0aWYgKCBmYWNlVmVydGV4VXZzLmxlbmd0aCA+IDAgKSB1dnMgPSBmYWNlVmVydGV4VXZzO1xuXG5cdFx0XHRcdGZvciAoIHZhciBmID0gMCwgZmwgPSBmYWNlcy5sZW5ndGg7IGYgPCBmbDsgZiArKyApIHtcblxuXHRcdFx0XHRcdHZhciBmYWNlID0gZmFjZXNbIGYgXTtcblx0XHRcdFx0XHR2YXIgZmFjZU1hdGVyaWFsID0gaXNNdWx0aU1hdGVyaWFsID8gbWF0ZXJpYWxbIGZhY2UubWF0ZXJpYWxJbmRleCBdIDogbWF0ZXJpYWw7XG5cblx0XHRcdFx0XHRpZiAoIGZhY2VNYXRlcmlhbCA9PT0gdW5kZWZpbmVkICkgY29udGludWU7XG5cblx0XHRcdFx0XHRmdkEgPSB2ZXJ0aWNlc1sgZmFjZS5hIF07XG5cdFx0XHRcdFx0ZnZCID0gdmVydGljZXNbIGZhY2UuYiBdO1xuXHRcdFx0XHRcdGZ2QyA9IHZlcnRpY2VzWyBmYWNlLmMgXTtcblxuXHRcdFx0XHRcdGlmICggZmFjZU1hdGVyaWFsLm1vcnBoVGFyZ2V0cyA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdFx0dmFyIG1vcnBoVGFyZ2V0cyA9IGdlb21ldHJ5Lm1vcnBoVGFyZ2V0cztcblx0XHRcdFx0XHRcdHZhciBtb3JwaEluZmx1ZW5jZXMgPSB0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztcblxuXHRcdFx0XHRcdFx0dkEuc2V0KCAwLCAwLCAwICk7XG5cdFx0XHRcdFx0XHR2Qi5zZXQoIDAsIDAsIDAgKTtcblx0XHRcdFx0XHRcdHZDLnNldCggMCwgMCwgMCApO1xuXG5cdFx0XHRcdFx0XHRmb3IgKCB2YXIgdCA9IDAsIHRsID0gbW9ycGhUYXJnZXRzLmxlbmd0aDsgdCA8IHRsOyB0ICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdHZhciBpbmZsdWVuY2UgPSBtb3JwaEluZmx1ZW5jZXNbIHQgXTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIGluZmx1ZW5jZSA9PT0gMCApIGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0XHRcdHZhciB0YXJnZXRzID0gbW9ycGhUYXJnZXRzWyB0IF0udmVydGljZXM7XG5cblx0XHRcdFx0XHRcdFx0dkEuYWRkU2NhbGVkVmVjdG9yKCB0ZW1wQS5zdWJWZWN0b3JzKCB0YXJnZXRzWyBmYWNlLmEgXSwgZnZBICksIGluZmx1ZW5jZSApO1xuXHRcdFx0XHRcdFx0XHR2Qi5hZGRTY2FsZWRWZWN0b3IoIHRlbXBCLnN1YlZlY3RvcnMoIHRhcmdldHNbIGZhY2UuYiBdLCBmdkIgKSwgaW5mbHVlbmNlICk7XG5cdFx0XHRcdFx0XHRcdHZDLmFkZFNjYWxlZFZlY3RvciggdGVtcEMuc3ViVmVjdG9ycyggdGFyZ2V0c1sgZmFjZS5jIF0sIGZ2QyApLCBpbmZsdWVuY2UgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR2QS5hZGQoIGZ2QSApO1xuXHRcdFx0XHRcdFx0dkIuYWRkKCBmdkIgKTtcblx0XHRcdFx0XHRcdHZDLmFkZCggZnZDICk7XG5cblx0XHRcdFx0XHRcdGZ2QSA9IHZBO1xuXHRcdFx0XHRcdFx0ZnZCID0gdkI7XG5cdFx0XHRcdFx0XHRmdkMgPSB2QztcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGludGVyc2VjdGlvbiA9IGNoZWNrSW50ZXJzZWN0aW9uKCB0aGlzLCByYXljYXN0ZXIsIHJheSwgZnZBLCBmdkIsIGZ2QywgaW50ZXJzZWN0aW9uUG9pbnQgKTtcblxuXHRcdFx0XHRcdGlmICggaW50ZXJzZWN0aW9uICkge1xuXG5cdFx0XHRcdFx0XHRpZiAoIHV2cyAmJiB1dnNbIGYgXSApIHtcblxuXHRcdFx0XHRcdFx0XHR2YXIgdXZzX2YgPSB1dnNbIGYgXTtcblx0XHRcdFx0XHRcdFx0dXZBLmNvcHkoIHV2c19mWyAwIF0gKTtcblx0XHRcdFx0XHRcdFx0dXZCLmNvcHkoIHV2c19mWyAxIF0gKTtcblx0XHRcdFx0XHRcdFx0dXZDLmNvcHkoIHV2c19mWyAyIF0gKTtcblxuXHRcdFx0XHRcdFx0XHRpbnRlcnNlY3Rpb24udXYgPSB1dkludGVyc2VjdGlvbiggaW50ZXJzZWN0aW9uUG9pbnQsIGZ2QSwgZnZCLCBmdkMsIHV2QSwgdXZCLCB1dkMgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpbnRlcnNlY3Rpb24uZmFjZSA9IGZhY2U7XG5cdFx0XHRcdFx0XHRpbnRlcnNlY3Rpb24uZmFjZUluZGV4ID0gZjtcblx0XHRcdFx0XHRcdGludGVyc2VjdHMucHVzaCggaW50ZXJzZWN0aW9uICk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdH0oKSApLFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoIHRoaXMuZ2VvbWV0cnksIHRoaXMubWF0ZXJpYWwgKS5jb3B5KCB0aGlzICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gQm94R2VvbWV0cnlcblxuZnVuY3Rpb24gQm94R2VvbWV0cnkoIHdpZHRoLCBoZWlnaHQsIGRlcHRoLCB3aWR0aFNlZ21lbnRzLCBoZWlnaHRTZWdtZW50cywgZGVwdGhTZWdtZW50cyApIHtcblxuXHRHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0JveEdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0d2lkdGg6IHdpZHRoLFxuXHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdGRlcHRoOiBkZXB0aCxcblx0XHR3aWR0aFNlZ21lbnRzOiB3aWR0aFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50cyxcblx0XHRkZXB0aFNlZ21lbnRzOiBkZXB0aFNlZ21lbnRzXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBCb3hCdWZmZXJHZW9tZXRyeSggd2lkdGgsIGhlaWdodCwgZGVwdGgsIHdpZHRoU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCBkZXB0aFNlZ21lbnRzICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuQm94R2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5Cb3hHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBCb3hHZW9tZXRyeTtcblxuLy8gQm94QnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gQm94QnVmZmVyR2VvbWV0cnkoIHdpZHRoLCBoZWlnaHQsIGRlcHRoLCB3aWR0aFNlZ21lbnRzLCBoZWlnaHRTZWdtZW50cywgZGVwdGhTZWdtZW50cyApIHtcblxuXHRCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0JveEJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0d2lkdGg6IHdpZHRoLFxuXHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdGRlcHRoOiBkZXB0aCxcblx0XHR3aWR0aFNlZ21lbnRzOiB3aWR0aFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50cyxcblx0XHRkZXB0aFNlZ21lbnRzOiBkZXB0aFNlZ21lbnRzXG5cdH07XG5cblx0dmFyIHNjb3BlID0gdGhpcztcblxuXHQvLyBzZWdtZW50c1xuXG5cdHdpZHRoU2VnbWVudHMgPSBNYXRoLmZsb29yKCB3aWR0aFNlZ21lbnRzICkgfHwgMTtcblx0aGVpZ2h0U2VnbWVudHMgPSBNYXRoLmZsb29yKCBoZWlnaHRTZWdtZW50cyApIHx8IDE7XG5cdGRlcHRoU2VnbWVudHMgPSBNYXRoLmZsb29yKCBkZXB0aFNlZ21lbnRzICkgfHwgMTtcblxuXHQvLyBidWZmZXJzXG5cblx0dmFyIGluZGljZXMgPSBbXTtcblx0dmFyIHZlcnRpY2VzID0gW107XG5cdHZhciBub3JtYWxzID0gW107XG5cdHZhciB1dnMgPSBbXTtcblxuXHQvLyBoZWxwZXIgdmFyaWFibGVzXG5cblx0dmFyIG51bWJlck9mVmVydGljZXMgPSAwO1xuXHR2YXIgZ3JvdXBTdGFydCA9IDA7XG5cblx0Ly8gYnVpbGQgZWFjaCBzaWRlIG9mIHRoZSBib3ggZ2VvbWV0cnlcblxuXHRidWlsZFBsYW5lKCAneicsICd5JywgJ3gnLCAtIDEsIC0gMSwgZGVwdGgsIGhlaWdodCwgICB3aWR0aCwgIGRlcHRoU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCAwICk7IC8vIHB4XG5cdGJ1aWxkUGxhbmUoICd6JywgJ3knLCAneCcsICAgMSwgLSAxLCBkZXB0aCwgaGVpZ2h0LCAtIHdpZHRoLCAgZGVwdGhTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIDEgKTsgLy8gbnhcblx0YnVpbGRQbGFuZSggJ3gnLCAneicsICd5JywgICAxLCAgIDEsIHdpZHRoLCBkZXB0aCwgICAgaGVpZ2h0LCB3aWR0aFNlZ21lbnRzLCBkZXB0aFNlZ21lbnRzLCAgMiApOyAvLyBweVxuXHRidWlsZFBsYW5lKCAneCcsICd6JywgJ3knLCAgIDEsIC0gMSwgd2lkdGgsIGRlcHRoLCAgLSBoZWlnaHQsIHdpZHRoU2VnbWVudHMsIGRlcHRoU2VnbWVudHMsICAzICk7IC8vIG55XG5cdGJ1aWxkUGxhbmUoICd4JywgJ3knLCAneicsICAgMSwgLSAxLCB3aWR0aCwgaGVpZ2h0LCAgIGRlcHRoLCAgd2lkdGhTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIDQgKTsgLy8gcHpcblx0YnVpbGRQbGFuZSggJ3gnLCAneScsICd6JywgLSAxLCAtIDEsIHdpZHRoLCBoZWlnaHQsIC0gZGVwdGgsICB3aWR0aFNlZ21lbnRzLCBoZWlnaHRTZWdtZW50cywgNSApOyAvLyBuelxuXG5cdC8vIGJ1aWxkIGdlb21ldHJ5XG5cblx0dGhpcy5zZXRJbmRleCggaW5kaWNlcyApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggbm9ybWFscywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkgKTtcblxuXHRmdW5jdGlvbiBidWlsZFBsYW5lKCB1LCB2LCB3LCB1ZGlyLCB2ZGlyLCB3aWR0aCwgaGVpZ2h0LCBkZXB0aCwgZ3JpZFgsIGdyaWRZLCBtYXRlcmlhbEluZGV4ICkge1xuXG5cdFx0dmFyIHNlZ21lbnRXaWR0aCA9IHdpZHRoIC8gZ3JpZFg7XG5cdFx0dmFyIHNlZ21lbnRIZWlnaHQgPSBoZWlnaHQgLyBncmlkWTtcblxuXHRcdHZhciB3aWR0aEhhbGYgPSB3aWR0aCAvIDI7XG5cdFx0dmFyIGhlaWdodEhhbGYgPSBoZWlnaHQgLyAyO1xuXHRcdHZhciBkZXB0aEhhbGYgPSBkZXB0aCAvIDI7XG5cblx0XHR2YXIgZ3JpZFgxID0gZ3JpZFggKyAxO1xuXHRcdHZhciBncmlkWTEgPSBncmlkWSArIDE7XG5cblx0XHR2YXIgdmVydGV4Q291bnRlciA9IDA7XG5cdFx0dmFyIGdyb3VwQ291bnQgPSAwO1xuXG5cdFx0dmFyIGl4LCBpeTtcblxuXHRcdHZhciB2ZWN0b3IgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0Ly8gZ2VuZXJhdGUgdmVydGljZXMsIG5vcm1hbHMgYW5kIHV2c1xuXG5cdFx0Zm9yICggaXkgPSAwOyBpeSA8IGdyaWRZMTsgaXkgKysgKSB7XG5cblx0XHRcdHZhciB5ID0gaXkgKiBzZWdtZW50SGVpZ2h0IC0gaGVpZ2h0SGFsZjtcblxuXHRcdFx0Zm9yICggaXggPSAwOyBpeCA8IGdyaWRYMTsgaXggKysgKSB7XG5cblx0XHRcdFx0dmFyIHggPSBpeCAqIHNlZ21lbnRXaWR0aCAtIHdpZHRoSGFsZjtcblxuXHRcdFx0XHQvLyBzZXQgdmFsdWVzIHRvIGNvcnJlY3QgdmVjdG9yIGNvbXBvbmVudFxuXG5cdFx0XHRcdHZlY3RvclsgdSBdID0geCAqIHVkaXI7XG5cdFx0XHRcdHZlY3RvclsgdiBdID0geSAqIHZkaXI7XG5cdFx0XHRcdHZlY3RvclsgdyBdID0gZGVwdGhIYWxmO1xuXG5cdFx0XHRcdC8vIG5vdyBhcHBseSB2ZWN0b3IgdG8gdmVydGV4IGJ1ZmZlclxuXG5cdFx0XHRcdHZlcnRpY2VzLnB1c2goIHZlY3Rvci54LCB2ZWN0b3IueSwgdmVjdG9yLnogKTtcblxuXHRcdFx0XHQvLyBzZXQgdmFsdWVzIHRvIGNvcnJlY3QgdmVjdG9yIGNvbXBvbmVudFxuXG5cdFx0XHRcdHZlY3RvclsgdSBdID0gMDtcblx0XHRcdFx0dmVjdG9yWyB2IF0gPSAwO1xuXHRcdFx0XHR2ZWN0b3JbIHcgXSA9IGRlcHRoID4gMCA/IDEgOiAtIDE7XG5cblx0XHRcdFx0Ly8gbm93IGFwcGx5IHZlY3RvciB0byBub3JtYWwgYnVmZmVyXG5cblx0XHRcdFx0bm9ybWFscy5wdXNoKCB2ZWN0b3IueCwgdmVjdG9yLnksIHZlY3Rvci56ICk7XG5cblx0XHRcdFx0Ly8gdXZzXG5cblx0XHRcdFx0dXZzLnB1c2goIGl4IC8gZ3JpZFggKTtcblx0XHRcdFx0dXZzLnB1c2goIDEgLSAoIGl5IC8gZ3JpZFkgKSApO1xuXG5cdFx0XHRcdC8vIGNvdW50ZXJzXG5cblx0XHRcdFx0dmVydGV4Q291bnRlciArPSAxO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHQvLyBpbmRpY2VzXG5cblx0XHQvLyAxLiB5b3UgbmVlZCB0aHJlZSBpbmRpY2VzIHRvIGRyYXcgYSBzaW5nbGUgZmFjZVxuXHRcdC8vIDIuIGEgc2luZ2xlIHNlZ21lbnQgY29uc2lzdHMgb2YgdHdvIGZhY2VzXG5cdFx0Ly8gMy4gc28gd2UgbmVlZCB0byBnZW5lcmF0ZSBzaXggKDIqMykgaW5kaWNlcyBwZXIgc2VnbWVudFxuXG5cdFx0Zm9yICggaXkgPSAwOyBpeSA8IGdyaWRZOyBpeSArKyApIHtcblxuXHRcdFx0Zm9yICggaXggPSAwOyBpeCA8IGdyaWRYOyBpeCArKyApIHtcblxuXHRcdFx0XHR2YXIgYSA9IG51bWJlck9mVmVydGljZXMgKyBpeCArIGdyaWRYMSAqIGl5O1xuXHRcdFx0XHR2YXIgYiA9IG51bWJlck9mVmVydGljZXMgKyBpeCArIGdyaWRYMSAqICggaXkgKyAxICk7XG5cdFx0XHRcdHZhciBjID0gbnVtYmVyT2ZWZXJ0aWNlcyArICggaXggKyAxICkgKyBncmlkWDEgKiAoIGl5ICsgMSApO1xuXHRcdFx0XHR2YXIgZCA9IG51bWJlck9mVmVydGljZXMgKyAoIGl4ICsgMSApICsgZ3JpZFgxICogaXk7XG5cblx0XHRcdFx0Ly8gZmFjZXNcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGEsIGIsIGQgKTtcblx0XHRcdFx0aW5kaWNlcy5wdXNoKCBiLCBjLCBkICk7XG5cblx0XHRcdFx0Ly8gaW5jcmVhc2UgY291bnRlclxuXG5cdFx0XHRcdGdyb3VwQ291bnQgKz0gNjtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gYWRkIGEgZ3JvdXAgdG8gdGhlIGdlb21ldHJ5LiB0aGlzIHdpbGwgZW5zdXJlIG11bHRpIG1hdGVyaWFsIHN1cHBvcnRcblxuXHRcdHNjb3BlLmFkZEdyb3VwKCBncm91cFN0YXJ0LCBncm91cENvdW50LCBtYXRlcmlhbEluZGV4ICk7XG5cblx0XHQvLyBjYWxjdWxhdGUgbmV3IHN0YXJ0IHZhbHVlIGZvciBncm91cHNcblxuXHRcdGdyb3VwU3RhcnQgKz0gZ3JvdXBDb3VudDtcblxuXHRcdC8vIHVwZGF0ZSB0b3RhbCBudW1iZXIgb2YgdmVydGljZXNcblxuXHRcdG51bWJlck9mVmVydGljZXMgKz0gdmVydGV4Q291bnRlcjtcblxuXHR9XG5cbn1cblxuQm94QnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5Cb3hCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBCb3hCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG4vLyBQbGFuZUdlb21ldHJ5XG5cbmZ1bmN0aW9uIFBsYW5lR2VvbWV0cnkoIHdpZHRoLCBoZWlnaHQsIHdpZHRoU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzICkge1xuXG5cdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnUGxhbmVHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHdpZHRoOiB3aWR0aCxcblx0XHRoZWlnaHQ6IGhlaWdodCxcblx0XHR3aWR0aFNlZ21lbnRzOiB3aWR0aFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50c1xuXHR9O1xuXG5cdHRoaXMuZnJvbUJ1ZmZlckdlb21ldHJ5KCBuZXcgUGxhbmVCdWZmZXJHZW9tZXRyeSggd2lkdGgsIGhlaWdodCwgd2lkdGhTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMgKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5QbGFuZUdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuUGxhbmVHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBQbGFuZUdlb21ldHJ5O1xuXG4vLyBQbGFuZUJ1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIFBsYW5lQnVmZmVyR2VvbWV0cnkoIHdpZHRoLCBoZWlnaHQsIHdpZHRoU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnUGxhbmVCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHdpZHRoOiB3aWR0aCxcblx0XHRoZWlnaHQ6IGhlaWdodCxcblx0XHR3aWR0aFNlZ21lbnRzOiB3aWR0aFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50c1xuXHR9O1xuXG5cdHZhciB3aWR0aF9oYWxmID0gd2lkdGggLyAyO1xuXHR2YXIgaGVpZ2h0X2hhbGYgPSBoZWlnaHQgLyAyO1xuXG5cdHZhciBncmlkWCA9IE1hdGguZmxvb3IoIHdpZHRoU2VnbWVudHMgKSB8fCAxO1xuXHR2YXIgZ3JpZFkgPSBNYXRoLmZsb29yKCBoZWlnaHRTZWdtZW50cyApIHx8IDE7XG5cblx0dmFyIGdyaWRYMSA9IGdyaWRYICsgMTtcblx0dmFyIGdyaWRZMSA9IGdyaWRZICsgMTtcblxuXHR2YXIgc2VnbWVudF93aWR0aCA9IHdpZHRoIC8gZ3JpZFg7XG5cdHZhciBzZWdtZW50X2hlaWdodCA9IGhlaWdodCAvIGdyaWRZO1xuXG5cdHZhciBpeCwgaXk7XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0Ly8gZ2VuZXJhdGUgdmVydGljZXMsIG5vcm1hbHMgYW5kIHV2c1xuXG5cdGZvciAoIGl5ID0gMDsgaXkgPCBncmlkWTE7IGl5ICsrICkge1xuXG5cdFx0dmFyIHkgPSBpeSAqIHNlZ21lbnRfaGVpZ2h0IC0gaGVpZ2h0X2hhbGY7XG5cblx0XHRmb3IgKCBpeCA9IDA7IGl4IDwgZ3JpZFgxOyBpeCArKyApIHtcblxuXHRcdFx0dmFyIHggPSBpeCAqIHNlZ21lbnRfd2lkdGggLSB3aWR0aF9oYWxmO1xuXG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCB4LCAtIHksIDAgKTtcblxuXHRcdFx0bm9ybWFscy5wdXNoKCAwLCAwLCAxICk7XG5cblx0XHRcdHV2cy5wdXNoKCBpeCAvIGdyaWRYICk7XG5cdFx0XHR1dnMucHVzaCggMSAtICggaXkgLyBncmlkWSApICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIGluZGljZXNcblxuXHRmb3IgKCBpeSA9IDA7IGl5IDwgZ3JpZFk7IGl5ICsrICkge1xuXG5cdFx0Zm9yICggaXggPSAwOyBpeCA8IGdyaWRYOyBpeCArKyApIHtcblxuXHRcdFx0dmFyIGEgPSBpeCArIGdyaWRYMSAqIGl5O1xuXHRcdFx0dmFyIGIgPSBpeCArIGdyaWRYMSAqICggaXkgKyAxICk7XG5cdFx0XHR2YXIgYyA9ICggaXggKyAxICkgKyBncmlkWDEgKiAoIGl5ICsgMSApO1xuXHRcdFx0dmFyIGQgPSAoIGl4ICsgMSApICsgZ3JpZFgxICogaXk7XG5cblx0XHRcdC8vIGZhY2VzXG5cblx0XHRcdGluZGljZXMucHVzaCggYSwgYiwgZCApO1xuXHRcdFx0aW5kaWNlcy5wdXNoKCBiLCBjLCBkICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIGJ1aWxkIGdlb21ldHJ5XG5cblx0dGhpcy5zZXRJbmRleCggaW5kaWNlcyApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggbm9ybWFscywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkgKTtcblxufVxuXG5QbGFuZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuUGxhbmVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBQbGFuZUJ1ZmZlckdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4qL1xuXG5mdW5jdGlvbiBDYW1lcmEoKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdDYW1lcmEnO1xuXG5cdHRoaXMubWF0cml4V29ybGRJbnZlcnNlID0gbmV3IE1hdHJpeDQoKTtcblx0dGhpcy5wcm9qZWN0aW9uTWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxufVxuXG5DYW1lcmEucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogQ2FtZXJhLFxuXG5cdGlzQ2FtZXJhOiB0cnVlLFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0T2JqZWN0M0QucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLm1hdHJpeFdvcmxkSW52ZXJzZS5jb3B5KCBzb3VyY2UubWF0cml4V29ybGRJbnZlcnNlICk7XG5cdFx0dGhpcy5wcm9qZWN0aW9uTWF0cml4LmNvcHkoIHNvdXJjZS5wcm9qZWN0aW9uTWF0cml4ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldFdvcmxkRGlyZWN0aW9uOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZ2V0V29ybGREaXJlY3Rpb24oIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0XHR2YXIgcmVzdWx0ID0gb3B0aW9uYWxUYXJnZXQgfHwgbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0dGhpcy5nZXRXb3JsZFF1YXRlcm5pb24oIHF1YXRlcm5pb24gKTtcblxuXHRcdFx0cmV0dXJuIHJlc3VsdC5zZXQoIDAsIDAsIC0gMSApLmFwcGx5UXVhdGVybmlvbiggcXVhdGVybmlvbiApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBncmVnZ21hbiAvIGh0dHA6Ly9nYW1lcy5ncmVnZ21hbi5jb20vXG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwOi8vd3d3LmxhYjRnYW1lcy5uZXQveno4NS9ibG9nXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gUGVyc3BlY3RpdmVDYW1lcmEoIGZvdiwgYXNwZWN0LCBuZWFyLCBmYXIgKSB7XG5cblx0Q2FtZXJhLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnUGVyc3BlY3RpdmVDYW1lcmEnO1xuXG5cdHRoaXMuZm92ID0gZm92ICE9PSB1bmRlZmluZWQgPyBmb3YgOiA1MDtcblx0dGhpcy56b29tID0gMTtcblxuXHR0aGlzLm5lYXIgPSBuZWFyICE9PSB1bmRlZmluZWQgPyBuZWFyIDogMC4xO1xuXHR0aGlzLmZhciA9IGZhciAhPT0gdW5kZWZpbmVkID8gZmFyIDogMjAwMDtcblx0dGhpcy5mb2N1cyA9IDEwO1xuXG5cdHRoaXMuYXNwZWN0ID0gYXNwZWN0ICE9PSB1bmRlZmluZWQgPyBhc3BlY3QgOiAxO1xuXHR0aGlzLnZpZXcgPSBudWxsO1xuXG5cdHRoaXMuZmlsbUdhdWdlID0gMzU7XHQvLyB3aWR0aCBvZiB0aGUgZmlsbSAoZGVmYXVsdCBpbiBtaWxsaW1ldGVycylcblx0dGhpcy5maWxtT2Zmc2V0ID0gMDtcdC8vIGhvcml6b250YWwgZmlsbSBvZmZzZXQgKHNhbWUgdW5pdCBhcyBnYXVnZSlcblxuXHR0aGlzLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxufVxuXG5QZXJzcGVjdGl2ZUNhbWVyYS5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBDYW1lcmEucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogUGVyc3BlY3RpdmVDYW1lcmEsXG5cblx0aXNQZXJzcGVjdGl2ZUNhbWVyYTogdHJ1ZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdENhbWVyYS5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHRcdHRoaXMuZm92ID0gc291cmNlLmZvdjtcblx0XHR0aGlzLnpvb20gPSBzb3VyY2Uuem9vbTtcblxuXHRcdHRoaXMubmVhciA9IHNvdXJjZS5uZWFyO1xuXHRcdHRoaXMuZmFyID0gc291cmNlLmZhcjtcblx0XHR0aGlzLmZvY3VzID0gc291cmNlLmZvY3VzO1xuXG5cdFx0dGhpcy5hc3BlY3QgPSBzb3VyY2UuYXNwZWN0O1xuXHRcdHRoaXMudmlldyA9IHNvdXJjZS52aWV3ID09PSBudWxsID8gbnVsbCA6IE9iamVjdC5hc3NpZ24oIHt9LCBzb3VyY2UudmlldyApO1xuXG5cdFx0dGhpcy5maWxtR2F1Z2UgPSBzb3VyY2UuZmlsbUdhdWdlO1xuXHRcdHRoaXMuZmlsbU9mZnNldCA9IHNvdXJjZS5maWxtT2Zmc2V0O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2V0cyB0aGUgRk9WIGJ5IGZvY2FsIGxlbmd0aCBpbiByZXNwZWN0IHRvIHRoZSBjdXJyZW50IC5maWxtR2F1Z2UuXG5cdCAqXG5cdCAqIFRoZSBkZWZhdWx0IGZpbG0gZ2F1Z2UgaXMgMzUsIHNvIHRoYXQgdGhlIGZvY2FsIGxlbmd0aCBjYW4gYmUgc3BlY2lmaWVkIGZvclxuXHQgKiBhIDM1bW0gKGZ1bGwgZnJhbWUpIGNhbWVyYS5cblx0ICpcblx0ICogVmFsdWVzIGZvciBmb2NhbCBsZW5ndGggYW5kIGZpbG0gZ2F1Z2UgbXVzdCBoYXZlIHRoZSBzYW1lIHVuaXQuXG5cdCAqL1xuXHRzZXRGb2NhbExlbmd0aDogZnVuY3Rpb24gKCBmb2NhbExlbmd0aCApIHtcblxuXHRcdC8vIHNlZSBodHRwOi8vd3d3LmJvYmF0a2lucy5jb20vcGhvdG9ncmFwaHkvdGVjaG5pY2FsL2ZpZWxkX29mX3ZpZXcuaHRtbFxuXHRcdHZhciB2RXh0ZW50U2xvcGUgPSAwLjUgKiB0aGlzLmdldEZpbG1IZWlnaHQoKSAvIGZvY2FsTGVuZ3RoO1xuXG5cdFx0dGhpcy5mb3YgPSBfTWF0aC5SQUQyREVHICogMiAqIE1hdGguYXRhbiggdkV4dGVudFNsb3BlICk7XG5cdFx0dGhpcy51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG5cblx0fSxcblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgZm9jYWwgbGVuZ3RoIGZyb20gdGhlIGN1cnJlbnQgLmZvdiBhbmQgLmZpbG1HYXVnZS5cblx0ICovXG5cdGdldEZvY2FsTGVuZ3RoOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdkV4dGVudFNsb3BlID0gTWF0aC50YW4oIF9NYXRoLkRFRzJSQUQgKiAwLjUgKiB0aGlzLmZvdiApO1xuXG5cdFx0cmV0dXJuIDAuNSAqIHRoaXMuZ2V0RmlsbUhlaWdodCgpIC8gdkV4dGVudFNsb3BlO1xuXG5cdH0sXG5cblx0Z2V0RWZmZWN0aXZlRk9WOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gX01hdGguUkFEMkRFRyAqIDIgKiBNYXRoLmF0YW4oXG5cdFx0XHRcdE1hdGgudGFuKCBfTWF0aC5ERUcyUkFEICogMC41ICogdGhpcy5mb3YgKSAvIHRoaXMuem9vbSApO1xuXG5cdH0sXG5cblx0Z2V0RmlsbVdpZHRoOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyBmaWxtIG5vdCBjb21wbGV0ZWx5IGNvdmVyZWQgaW4gcG9ydHJhaXQgZm9ybWF0IChhc3BlY3QgPCAxKVxuXHRcdHJldHVybiB0aGlzLmZpbG1HYXVnZSAqIE1hdGgubWluKCB0aGlzLmFzcGVjdCwgMSApO1xuXG5cdH0sXG5cblx0Z2V0RmlsbUhlaWdodDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Ly8gZmlsbSBub3QgY29tcGxldGVseSBjb3ZlcmVkIGluIGxhbmRzY2FwZSBmb3JtYXQgKGFzcGVjdCA+IDEpXG5cdFx0cmV0dXJuIHRoaXMuZmlsbUdhdWdlIC8gTWF0aC5tYXgoIHRoaXMuYXNwZWN0LCAxICk7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2V0cyBhbiBvZmZzZXQgaW4gYSBsYXJnZXIgZnJ1c3R1bS4gVGhpcyBpcyB1c2VmdWwgZm9yIG11bHRpLXdpbmRvdyBvclxuXHQgKiBtdWx0aS1tb25pdG9yL211bHRpLW1hY2hpbmUgc2V0dXBzLlxuXHQgKlxuXHQgKiBGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgM3gyIG1vbml0b3JzIGFuZCBlYWNoIG1vbml0b3IgaXMgMTkyMHgxMDgwIGFuZFxuXHQgKiB0aGUgbW9uaXRvcnMgYXJlIGluIGdyaWQgbGlrZSB0aGlzXG5cdCAqXG5cdCAqICAgKy0tLSstLS0rLS0tK1xuXHQgKiAgIHwgQSB8IEIgfCBDIHxcblx0ICogICArLS0tKy0tLSstLS0rXG5cdCAqICAgfCBEIHwgRSB8IEYgfFxuXHQgKiAgICstLS0rLS0tKy0tLStcblx0ICpcblx0ICogdGhlbiBmb3IgZWFjaCBtb25pdG9yIHlvdSB3b3VsZCBjYWxsIGl0IGxpa2UgdGhpc1xuXHQgKlxuXHQgKiAgIHZhciB3ID0gMTkyMDtcblx0ICogICB2YXIgaCA9IDEwODA7XG5cdCAqICAgdmFyIGZ1bGxXaWR0aCA9IHcgKiAzO1xuXHQgKiAgIHZhciBmdWxsSGVpZ2h0ID0gaCAqIDI7XG5cdCAqXG5cdCAqICAgLS1BLS1cblx0ICogICBjYW1lcmEuc2V0T2Zmc2V0KCBmdWxsV2lkdGgsIGZ1bGxIZWlnaHQsIHcgKiAwLCBoICogMCwgdywgaCApO1xuXHQgKiAgIC0tQi0tXG5cdCAqICAgY2FtZXJhLnNldE9mZnNldCggZnVsbFdpZHRoLCBmdWxsSGVpZ2h0LCB3ICogMSwgaCAqIDAsIHcsIGggKTtcblx0ICogICAtLUMtLVxuXHQgKiAgIGNhbWVyYS5zZXRPZmZzZXQoIGZ1bGxXaWR0aCwgZnVsbEhlaWdodCwgdyAqIDIsIGggKiAwLCB3LCBoICk7XG5cdCAqICAgLS1ELS1cblx0ICogICBjYW1lcmEuc2V0T2Zmc2V0KCBmdWxsV2lkdGgsIGZ1bGxIZWlnaHQsIHcgKiAwLCBoICogMSwgdywgaCApO1xuXHQgKiAgIC0tRS0tXG5cdCAqICAgY2FtZXJhLnNldE9mZnNldCggZnVsbFdpZHRoLCBmdWxsSGVpZ2h0LCB3ICogMSwgaCAqIDEsIHcsIGggKTtcblx0ICogICAtLUYtLVxuXHQgKiAgIGNhbWVyYS5zZXRPZmZzZXQoIGZ1bGxXaWR0aCwgZnVsbEhlaWdodCwgdyAqIDIsIGggKiAxLCB3LCBoICk7XG5cdCAqXG5cdCAqICAgTm90ZSB0aGVyZSBpcyBubyByZWFzb24gbW9uaXRvcnMgaGF2ZSB0byBiZSB0aGUgc2FtZSBzaXplIG9yIGluIGEgZ3JpZC5cblx0ICovXG5cdHNldFZpZXdPZmZzZXQ6IGZ1bmN0aW9uICggZnVsbFdpZHRoLCBmdWxsSGVpZ2h0LCB4LCB5LCB3aWR0aCwgaGVpZ2h0ICkge1xuXG5cdFx0dGhpcy5hc3BlY3QgPSBmdWxsV2lkdGggLyBmdWxsSGVpZ2h0O1xuXG5cdFx0dGhpcy52aWV3ID0ge1xuXHRcdFx0ZnVsbFdpZHRoOiBmdWxsV2lkdGgsXG5cdFx0XHRmdWxsSGVpZ2h0OiBmdWxsSGVpZ2h0LFxuXHRcdFx0b2Zmc2V0WDogeCxcblx0XHRcdG9mZnNldFk6IHksXG5cdFx0XHR3aWR0aDogd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdH07XG5cblx0XHR0aGlzLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxuXHR9LFxuXG5cdGNsZWFyVmlld09mZnNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy52aWV3ID0gbnVsbDtcblx0XHR0aGlzLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxuXHR9LFxuXG5cdHVwZGF0ZVByb2plY3Rpb25NYXRyaXg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBuZWFyID0gdGhpcy5uZWFyLFxuXHRcdFx0dG9wID0gbmVhciAqIE1hdGgudGFuKFxuXHRcdFx0XHRcdF9NYXRoLkRFRzJSQUQgKiAwLjUgKiB0aGlzLmZvdiApIC8gdGhpcy56b29tLFxuXHRcdFx0aGVpZ2h0ID0gMiAqIHRvcCxcblx0XHRcdHdpZHRoID0gdGhpcy5hc3BlY3QgKiBoZWlnaHQsXG5cdFx0XHRsZWZ0ID0gLSAwLjUgKiB3aWR0aCxcblx0XHRcdHZpZXcgPSB0aGlzLnZpZXc7XG5cblx0XHRpZiAoIHZpZXcgIT09IG51bGwgKSB7XG5cblx0XHRcdHZhciBmdWxsV2lkdGggPSB2aWV3LmZ1bGxXaWR0aCxcblx0XHRcdFx0ZnVsbEhlaWdodCA9IHZpZXcuZnVsbEhlaWdodDtcblxuXHRcdFx0bGVmdCArPSB2aWV3Lm9mZnNldFggKiB3aWR0aCAvIGZ1bGxXaWR0aDtcblx0XHRcdHRvcCAtPSB2aWV3Lm9mZnNldFkgKiBoZWlnaHQgLyBmdWxsSGVpZ2h0O1xuXHRcdFx0d2lkdGggKj0gdmlldy53aWR0aCAvIGZ1bGxXaWR0aDtcblx0XHRcdGhlaWdodCAqPSB2aWV3LmhlaWdodCAvIGZ1bGxIZWlnaHQ7XG5cblx0XHR9XG5cblx0XHR2YXIgc2tldyA9IHRoaXMuZmlsbU9mZnNldDtcblx0XHRpZiAoIHNrZXcgIT09IDAgKSBsZWZ0ICs9IG5lYXIgKiBza2V3IC8gdGhpcy5nZXRGaWxtV2lkdGgoKTtcblxuXHRcdHRoaXMucHJvamVjdGlvbk1hdHJpeC5tYWtlUGVyc3BlY3RpdmUoIGxlZnQsIGxlZnQgKyB3aWR0aCwgdG9wLCB0b3AgLSBoZWlnaHQsIG5lYXIsIHRoaXMuZmFyICk7XG5cblx0fSxcblxuXHR0b0pTT046IGZ1bmN0aW9uICggbWV0YSApIHtcblxuXHRcdHZhciBkYXRhID0gT2JqZWN0M0QucHJvdG90eXBlLnRvSlNPTi5jYWxsKCB0aGlzLCBtZXRhICk7XG5cblx0XHRkYXRhLm9iamVjdC5mb3YgPSB0aGlzLmZvdjtcblx0XHRkYXRhLm9iamVjdC56b29tID0gdGhpcy56b29tO1xuXG5cdFx0ZGF0YS5vYmplY3QubmVhciA9IHRoaXMubmVhcjtcblx0XHRkYXRhLm9iamVjdC5mYXIgPSB0aGlzLmZhcjtcblx0XHRkYXRhLm9iamVjdC5mb2N1cyA9IHRoaXMuZm9jdXM7XG5cblx0XHRkYXRhLm9iamVjdC5hc3BlY3QgPSB0aGlzLmFzcGVjdDtcblxuXHRcdGlmICggdGhpcy52aWV3ICE9PSBudWxsICkgZGF0YS5vYmplY3QudmlldyA9IE9iamVjdC5hc3NpZ24oIHt9LCB0aGlzLnZpZXcgKTtcblxuXHRcdGRhdGEub2JqZWN0LmZpbG1HYXVnZSA9IHRoaXMuZmlsbUdhdWdlO1xuXHRcdGRhdGEub2JqZWN0LmZpbG1PZmZzZXQgPSB0aGlzLmZpbG1PZmZzZXQ7XG5cblx0XHRyZXR1cm4gZGF0YTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBhcm9zZSAvIGh0dHA6Ly9naXRodWIuY29tL2Fyb3NlXG4gKi9cblxuZnVuY3Rpb24gT3J0aG9ncmFwaGljQ2FtZXJhKCBsZWZ0LCByaWdodCwgdG9wLCBib3R0b20sIG5lYXIsIGZhciApIHtcblxuXHRDYW1lcmEuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdPcnRob2dyYXBoaWNDYW1lcmEnO1xuXG5cdHRoaXMuem9vbSA9IDE7XG5cdHRoaXMudmlldyA9IG51bGw7XG5cblx0dGhpcy5sZWZ0ID0gbGVmdDtcblx0dGhpcy5yaWdodCA9IHJpZ2h0O1xuXHR0aGlzLnRvcCA9IHRvcDtcblx0dGhpcy5ib3R0b20gPSBib3R0b207XG5cblx0dGhpcy5uZWFyID0gKCBuZWFyICE9PSB1bmRlZmluZWQgKSA/IG5lYXIgOiAwLjE7XG5cdHRoaXMuZmFyID0gKCBmYXIgIT09IHVuZGVmaW5lZCApID8gZmFyIDogMjAwMDtcblxuXHR0aGlzLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxufVxuXG5PcnRob2dyYXBoaWNDYW1lcmEucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggQ2FtZXJhLnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IE9ydGhvZ3JhcGhpY0NhbWVyYSxcblxuXHRpc09ydGhvZ3JhcGhpY0NhbWVyYTogdHJ1ZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdENhbWVyYS5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHRcdHRoaXMubGVmdCA9IHNvdXJjZS5sZWZ0O1xuXHRcdHRoaXMucmlnaHQgPSBzb3VyY2UucmlnaHQ7XG5cdFx0dGhpcy50b3AgPSBzb3VyY2UudG9wO1xuXHRcdHRoaXMuYm90dG9tID0gc291cmNlLmJvdHRvbTtcblx0XHR0aGlzLm5lYXIgPSBzb3VyY2UubmVhcjtcblx0XHR0aGlzLmZhciA9IHNvdXJjZS5mYXI7XG5cblx0XHR0aGlzLnpvb20gPSBzb3VyY2Uuem9vbTtcblx0XHR0aGlzLnZpZXcgPSBzb3VyY2UudmlldyA9PT0gbnVsbCA/IG51bGwgOiBPYmplY3QuYXNzaWduKCB7fSwgc291cmNlLnZpZXcgKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0Vmlld09mZnNldDogZnVuY3Rpb24oIGZ1bGxXaWR0aCwgZnVsbEhlaWdodCwgeCwgeSwgd2lkdGgsIGhlaWdodCApIHtcblxuXHRcdHRoaXMudmlldyA9IHtcblx0XHRcdGZ1bGxXaWR0aDogZnVsbFdpZHRoLFxuXHRcdFx0ZnVsbEhlaWdodDogZnVsbEhlaWdodCxcblx0XHRcdG9mZnNldFg6IHgsXG5cdFx0XHRvZmZzZXRZOiB5LFxuXHRcdFx0d2lkdGg6IHdpZHRoLFxuXHRcdFx0aGVpZ2h0OiBoZWlnaHRcblx0XHR9O1xuXG5cdFx0dGhpcy51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG5cblx0fSxcblxuXHRjbGVhclZpZXdPZmZzZXQ6IGZ1bmN0aW9uKCkge1xuXG5cdFx0dGhpcy52aWV3ID0gbnVsbDtcblx0XHR0aGlzLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcblxuXHR9LFxuXG5cdHVwZGF0ZVByb2plY3Rpb25NYXRyaXg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBkeCA9ICggdGhpcy5yaWdodCAtIHRoaXMubGVmdCApIC8gKCAyICogdGhpcy56b29tICk7XG5cdFx0dmFyIGR5ID0gKCB0aGlzLnRvcCAtIHRoaXMuYm90dG9tICkgLyAoIDIgKiB0aGlzLnpvb20gKTtcblx0XHR2YXIgY3ggPSAoIHRoaXMucmlnaHQgKyB0aGlzLmxlZnQgKSAvIDI7XG5cdFx0dmFyIGN5ID0gKCB0aGlzLnRvcCArIHRoaXMuYm90dG9tICkgLyAyO1xuXG5cdFx0dmFyIGxlZnQgPSBjeCAtIGR4O1xuXHRcdHZhciByaWdodCA9IGN4ICsgZHg7XG5cdFx0dmFyIHRvcCA9IGN5ICsgZHk7XG5cdFx0dmFyIGJvdHRvbSA9IGN5IC0gZHk7XG5cblx0XHRpZiAoIHRoaXMudmlldyAhPT0gbnVsbCApIHtcblxuXHRcdFx0dmFyIHpvb21XID0gdGhpcy56b29tIC8gKCB0aGlzLnZpZXcud2lkdGggLyB0aGlzLnZpZXcuZnVsbFdpZHRoICk7XG5cdFx0XHR2YXIgem9vbUggPSB0aGlzLnpvb20gLyAoIHRoaXMudmlldy5oZWlnaHQgLyB0aGlzLnZpZXcuZnVsbEhlaWdodCApO1xuXHRcdFx0dmFyIHNjYWxlVyA9ICggdGhpcy5yaWdodCAtIHRoaXMubGVmdCApIC8gdGhpcy52aWV3LndpZHRoO1xuXHRcdFx0dmFyIHNjYWxlSCA9ICggdGhpcy50b3AgLSB0aGlzLmJvdHRvbSApIC8gdGhpcy52aWV3LmhlaWdodDtcblxuXHRcdFx0bGVmdCArPSBzY2FsZVcgKiAoIHRoaXMudmlldy5vZmZzZXRYIC8gem9vbVcgKTtcblx0XHRcdHJpZ2h0ID0gbGVmdCArIHNjYWxlVyAqICggdGhpcy52aWV3LndpZHRoIC8gem9vbVcgKTtcblx0XHRcdHRvcCAtPSBzY2FsZUggKiAoIHRoaXMudmlldy5vZmZzZXRZIC8gem9vbUggKTtcblx0XHRcdGJvdHRvbSA9IHRvcCAtIHNjYWxlSCAqICggdGhpcy52aWV3LmhlaWdodCAvIHpvb21IICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLnByb2plY3Rpb25NYXRyaXgubWFrZU9ydGhvZ3JhcGhpYyggbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tLCB0aGlzLm5lYXIsIHRoaXMuZmFyICk7XG5cblx0fSxcblxuXHR0b0pTT046IGZ1bmN0aW9uICggbWV0YSApIHtcblxuXHRcdHZhciBkYXRhID0gT2JqZWN0M0QucHJvdG90eXBlLnRvSlNPTi5jYWxsKCB0aGlzLCBtZXRhICk7XG5cblx0XHRkYXRhLm9iamVjdC56b29tID0gdGhpcy56b29tO1xuXHRcdGRhdGEub2JqZWN0LmxlZnQgPSB0aGlzLmxlZnQ7XG5cdFx0ZGF0YS5vYmplY3QucmlnaHQgPSB0aGlzLnJpZ2h0O1xuXHRcdGRhdGEub2JqZWN0LnRvcCA9IHRoaXMudG9wO1xuXHRcdGRhdGEub2JqZWN0LmJvdHRvbSA9IHRoaXMuYm90dG9tO1xuXHRcdGRhdGEub2JqZWN0Lm5lYXIgPSB0aGlzLm5lYXI7XG5cdFx0ZGF0YS5vYmplY3QuZmFyID0gdGhpcy5mYXI7XG5cblx0XHRpZiAoIHRoaXMudmlldyAhPT0gbnVsbCApIGRhdGEub2JqZWN0LnZpZXcgPSBPYmplY3QuYXNzaWduKCB7fSwgdGhpcy52aWV3ICk7XG5cblx0XHRyZXR1cm4gZGF0YTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFdlYkdMQXR0cmlidXRlcyggZ2wgKSB7XG5cblx0dmFyIGJ1ZmZlcnMgPSB7fTtcblxuXHRmdW5jdGlvbiBjcmVhdGVCdWZmZXIoIGF0dHJpYnV0ZSwgYnVmZmVyVHlwZSApIHtcblxuXHRcdHZhciBhcnJheSA9IGF0dHJpYnV0ZS5hcnJheTtcblx0XHR2YXIgdXNhZ2UgPSBhdHRyaWJ1dGUuZHluYW1pYyA/IGdsLkRZTkFNSUNfRFJBVyA6IGdsLlNUQVRJQ19EUkFXO1xuXG5cdFx0dmFyIGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuXG5cdFx0Z2wuYmluZEJ1ZmZlciggYnVmZmVyVHlwZSwgYnVmZmVyICk7XG5cdFx0Z2wuYnVmZmVyRGF0YSggYnVmZmVyVHlwZSwgYXJyYXksIHVzYWdlICk7XG5cblx0XHRhdHRyaWJ1dGUub25VcGxvYWRDYWxsYmFjaygpO1xuXG5cdFx0dmFyIHR5cGUgPSBnbC5GTE9BVDtcblxuXHRcdGlmICggYXJyYXkgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgKSB7XG5cblx0XHRcdHR5cGUgPSBnbC5GTE9BVDtcblxuXHRcdH0gZWxzZSBpZiAoIGFycmF5IGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oIFwiVW5zdXBwb3J0ZWQgZGF0YSBidWZmZXIgZm9ybWF0OiBGbG9hdDY0QXJyYXlcIiApO1xuXG5cdFx0fSBlbHNlIGlmICggYXJyYXkgaW5zdGFuY2VvZiBVaW50MTZBcnJheSApIHtcblxuXHRcdFx0dHlwZSA9IGdsLlVOU0lHTkVEX1NIT1JUO1xuXG5cdFx0fSBlbHNlIGlmICggYXJyYXkgaW5zdGFuY2VvZiBJbnQxNkFycmF5ICkge1xuXG5cdFx0XHR0eXBlID0gZ2wuU0hPUlQ7XG5cblx0XHR9IGVsc2UgaWYgKCBhcnJheSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ICkge1xuXG5cdFx0XHR0eXBlID0gZ2wuVU5TSUdORURfSU5UO1xuXG5cdFx0fSBlbHNlIGlmICggYXJyYXkgaW5zdGFuY2VvZiBJbnQzMkFycmF5ICkge1xuXG5cdFx0XHR0eXBlID0gZ2wuSU5UO1xuXG5cdFx0fSBlbHNlIGlmICggYXJyYXkgaW5zdGFuY2VvZiBJbnQ4QXJyYXkgKSB7XG5cblx0XHRcdHR5cGUgPSBnbC5CWVRFO1xuXG5cdFx0fSBlbHNlIGlmICggYXJyYXkgaW5zdGFuY2VvZiBVaW50OEFycmF5ICkge1xuXG5cdFx0XHR0eXBlID0gZ2wuVU5TSUdORURfQllURTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRidWZmZXI6IGJ1ZmZlcixcblx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRieXRlc1BlckVsZW1lbnQ6IGFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULFxuXHRcdFx0dmVyc2lvbjogYXR0cmlidXRlLnZlcnNpb25cblx0XHR9O1xuXG5cdH1cblxuXHRmdW5jdGlvbiB1cGRhdGVCdWZmZXIoIGJ1ZmZlciwgYXR0cmlidXRlLCBidWZmZXJUeXBlICkge1xuXG5cdFx0dmFyIGFycmF5ID0gYXR0cmlidXRlLmFycmF5O1xuXHRcdHZhciB1cGRhdGVSYW5nZSA9IGF0dHJpYnV0ZS51cGRhdGVSYW5nZTtcblxuXHRcdGdsLmJpbmRCdWZmZXIoIGJ1ZmZlclR5cGUsIGJ1ZmZlciApO1xuXG5cdFx0aWYgKCBhdHRyaWJ1dGUuZHluYW1pYyA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGdsLmJ1ZmZlckRhdGEoIGJ1ZmZlclR5cGUsIGFycmF5LCBnbC5TVEFUSUNfRFJBVyApO1xuXG5cdFx0fSBlbHNlIGlmICggdXBkYXRlUmFuZ2UuY291bnQgPT09IC0gMSApIHtcblxuXHRcdFx0Ly8gTm90IHVzaW5nIHVwZGF0ZSByYW5nZXNcblxuXHRcdFx0Z2wuYnVmZmVyU3ViRGF0YSggYnVmZmVyVHlwZSwgMCwgYXJyYXkgKTtcblxuXHRcdH0gZWxzZSBpZiAoIHVwZGF0ZVJhbmdlLmNvdW50ID09PSAwICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xPYmplY3RzLnVwZGF0ZUJ1ZmZlcjogZHluYW1pYyBUSFJFRS5CdWZmZXJBdHRyaWJ1dGUgbWFya2VkIGFzIG5lZWRzVXBkYXRlIGJ1dCB1cGRhdGVSYW5nZS5jb3VudCBpcyAwLCBlbnN1cmUgeW91IGFyZSB1c2luZyBzZXQgbWV0aG9kcyBvciB1cGRhdGluZyBtYW51YWxseS4nICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRnbC5idWZmZXJTdWJEYXRhKCBidWZmZXJUeXBlLCB1cGRhdGVSYW5nZS5vZmZzZXQgKiBhcnJheS5CWVRFU19QRVJfRUxFTUVOVCxcblx0XHRcdFx0YXJyYXkuc3ViYXJyYXkoIHVwZGF0ZVJhbmdlLm9mZnNldCwgdXBkYXRlUmFuZ2Uub2Zmc2V0ICsgdXBkYXRlUmFuZ2UuY291bnQgKSApO1xuXG5cdFx0XHR1cGRhdGVSYW5nZS5jb3VudCA9IDA7IC8vIHJlc2V0IHJhbmdlXG5cblx0XHR9XG5cblx0fVxuXG5cdC8vXG5cblx0ZnVuY3Rpb24gZ2V0KCBhdHRyaWJ1dGUgKSB7XG5cblx0XHRpZiAoIGF0dHJpYnV0ZS5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlICkgYXR0cmlidXRlID0gYXR0cmlidXRlLmRhdGE7XG5cblx0XHRyZXR1cm4gYnVmZmVyc1sgYXR0cmlidXRlLnV1aWQgXTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVtb3ZlKCBhdHRyaWJ1dGUgKSB7XG5cblx0XHR2YXIgZGF0YSA9IGJ1ZmZlcnNbIGF0dHJpYnV0ZS51dWlkIF07XG5cblx0XHRpZiAoIGRhdGEgKSB7XG5cblx0XHRcdGdsLmRlbGV0ZUJ1ZmZlciggZGF0YS5idWZmZXIgKTtcblxuXHRcdFx0ZGVsZXRlIGJ1ZmZlcnNbIGF0dHJpYnV0ZS51dWlkIF07XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHVwZGF0ZSggYXR0cmlidXRlLCBidWZmZXJUeXBlICkge1xuXG5cdFx0aWYgKCBhdHRyaWJ1dGUuaXNJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSApIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZS5kYXRhO1xuXG5cdFx0dmFyIGRhdGEgPSBidWZmZXJzWyBhdHRyaWJ1dGUudXVpZCBdO1xuXG5cdFx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGJ1ZmZlcnNbIGF0dHJpYnV0ZS51dWlkIF0gPSBjcmVhdGVCdWZmZXIoIGF0dHJpYnV0ZSwgYnVmZmVyVHlwZSApO1xuXG5cdFx0fSBlbHNlIGlmICggZGF0YS52ZXJzaW9uIDwgYXR0cmlidXRlLnZlcnNpb24gKSB7XG5cblx0XHRcdHVwZGF0ZUJ1ZmZlciggZGF0YS5idWZmZXIsIGF0dHJpYnV0ZSwgYnVmZmVyVHlwZSApO1xuXG5cdFx0XHRkYXRhLnZlcnNpb24gPSBhdHRyaWJ1dGUudmVyc2lvbjtcblxuXHRcdH1cblxuXHR9XG5cblx0cmV0dXJuIHtcblxuXHRcdGdldDogZ2V0LFxuXHRcdHJlbW92ZTogcmVtb3ZlLFxuXHRcdHVwZGF0ZTogdXBkYXRlXG5cblx0fTtcblxufVxuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gcGFpbnRlclNvcnRTdGFibGUoIGEsIGIgKSB7XG5cblx0aWYgKCBhLnJlbmRlck9yZGVyICE9PSBiLnJlbmRlck9yZGVyICkge1xuXG5cdFx0cmV0dXJuIGEucmVuZGVyT3JkZXIgLSBiLnJlbmRlck9yZGVyO1xuXG5cdH0gZWxzZSBpZiAoIGEucHJvZ3JhbSAmJiBiLnByb2dyYW0gJiYgYS5wcm9ncmFtICE9PSBiLnByb2dyYW0gKSB7XG5cblx0XHRyZXR1cm4gYS5wcm9ncmFtLmlkIC0gYi5wcm9ncmFtLmlkO1xuXG5cdH0gZWxzZSBpZiAoIGEubWF0ZXJpYWwuaWQgIT09IGIubWF0ZXJpYWwuaWQgKSB7XG5cblx0XHRyZXR1cm4gYS5tYXRlcmlhbC5pZCAtIGIubWF0ZXJpYWwuaWQ7XG5cblx0fSBlbHNlIGlmICggYS56ICE9PSBiLnogKSB7XG5cblx0XHRyZXR1cm4gYS56IC0gYi56O1xuXG5cdH0gZWxzZSB7XG5cblx0XHRyZXR1cm4gYS5pZCAtIGIuaWQ7XG5cblx0fVxuXG59XG5cbmZ1bmN0aW9uIHJldmVyc2VQYWludGVyU29ydFN0YWJsZSggYSwgYiApIHtcblxuXHRpZiAoIGEucmVuZGVyT3JkZXIgIT09IGIucmVuZGVyT3JkZXIgKSB7XG5cblx0XHRyZXR1cm4gYS5yZW5kZXJPcmRlciAtIGIucmVuZGVyT3JkZXI7XG5cblx0fSBpZiAoIGEueiAhPT0gYi56ICkge1xuXG5cdFx0cmV0dXJuIGIueiAtIGEuejtcblxuXHR9IGVsc2Uge1xuXG5cdFx0cmV0dXJuIGEuaWQgLSBiLmlkO1xuXG5cdH1cblxufVxuXG5mdW5jdGlvbiBXZWJHTFJlbmRlckxpc3QoKSB7XG5cblx0dmFyIG9wYXF1ZSA9IFtdO1xuXHR2YXIgb3BhcXVlTGFzdEluZGV4ID0gLSAxO1xuXG5cdHZhciB0cmFuc3BhcmVudCA9IFtdO1xuXHR2YXIgdHJhbnNwYXJlbnRMYXN0SW5kZXggPSAtIDE7XG5cblx0ZnVuY3Rpb24gaW5pdCgpIHtcblxuXHRcdG9wYXF1ZUxhc3RJbmRleCA9IC0gMTtcblx0XHR0cmFuc3BhcmVudExhc3RJbmRleCA9IC0gMTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcHVzaCggb2JqZWN0LCBnZW9tZXRyeSwgbWF0ZXJpYWwsIHosIGdyb3VwICkge1xuXG5cdFx0dmFyIGFycmF5LCBpbmRleDtcblxuXHRcdC8vIGFsbG9jYXRlIHRoZSBuZXh0IHBvc2l0aW9uIGluIHRoZSBhcHByb3ByaWF0ZSBhcnJheVxuXG5cdFx0aWYgKCBtYXRlcmlhbC50cmFuc3BhcmVudCApIHtcblxuXHRcdFx0YXJyYXkgPSB0cmFuc3BhcmVudDtcblx0XHRcdGluZGV4ID0gKysgdHJhbnNwYXJlbnRMYXN0SW5kZXg7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRhcnJheSA9IG9wYXF1ZTtcblx0XHRcdGluZGV4ID0gKysgb3BhcXVlTGFzdEluZGV4O1xuXG5cdFx0fVxuXG5cdFx0Ly8gcmVjeWNsZSBleGlzdGluZyByZW5kZXIgaXRlbSBvciBncm93IHRoZSBhcnJheVxuXG5cdFx0dmFyIHJlbmRlckl0ZW0gPSBhcnJheVsgaW5kZXggXTtcblxuXHRcdGlmICggcmVuZGVySXRlbSApIHtcblxuXHRcdFx0cmVuZGVySXRlbS5pZCA9IG9iamVjdC5pZDtcblx0XHRcdHJlbmRlckl0ZW0ub2JqZWN0ID0gb2JqZWN0O1xuXHRcdFx0cmVuZGVySXRlbS5nZW9tZXRyeSA9IGdlb21ldHJ5O1xuXHRcdFx0cmVuZGVySXRlbS5tYXRlcmlhbCA9IG1hdGVyaWFsO1xuXHRcdFx0cmVuZGVySXRlbS5wcm9ncmFtID0gbWF0ZXJpYWwucHJvZ3JhbTtcblx0XHRcdHJlbmRlckl0ZW0ucmVuZGVyT3JkZXIgPSBvYmplY3QucmVuZGVyT3JkZXI7XG5cdFx0XHRyZW5kZXJJdGVtLnogPSB6O1xuXHRcdFx0cmVuZGVySXRlbS5ncm91cCA9IGdyb3VwO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0cmVuZGVySXRlbSA9IHtcblx0XHRcdFx0aWQ6IG9iamVjdC5pZCxcblx0XHRcdFx0b2JqZWN0OiBvYmplY3QsXG5cdFx0XHRcdGdlb21ldHJ5OiBnZW9tZXRyeSxcblx0XHRcdFx0bWF0ZXJpYWw6IG1hdGVyaWFsLFxuXHRcdFx0XHRwcm9ncmFtOiBtYXRlcmlhbC5wcm9ncmFtLFxuXHRcdFx0XHRyZW5kZXJPcmRlcjogb2JqZWN0LnJlbmRlck9yZGVyLFxuXHRcdFx0XHR6OiB6LFxuXHRcdFx0XHRncm91cDogZ3JvdXBcblx0XHRcdH07XG5cblx0XHRcdC8vIGFzc2VydCggaW5kZXggPT09IGFycmF5Lmxlbmd0aCApO1xuXHRcdFx0YXJyYXkucHVzaCggcmVuZGVySXRlbSApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBmaW5pc2goKSB7XG5cblx0XHRvcGFxdWUubGVuZ3RoID0gb3BhcXVlTGFzdEluZGV4ICsgMTtcblx0XHR0cmFuc3BhcmVudC5sZW5ndGggPSB0cmFuc3BhcmVudExhc3RJbmRleCArIDE7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHNvcnQoKSB7XG5cblx0XHRvcGFxdWUuc29ydCggcGFpbnRlclNvcnRTdGFibGUgKTtcblx0XHR0cmFuc3BhcmVudC5zb3J0KCByZXZlcnNlUGFpbnRlclNvcnRTdGFibGUgKTtcblxuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRvcGFxdWU6IG9wYXF1ZSxcblx0XHR0cmFuc3BhcmVudDogdHJhbnNwYXJlbnQsXG5cblx0XHRpbml0OiBpbml0LFxuXHRcdHB1c2g6IHB1c2gsXG5cdFx0ZmluaXNoOiBmaW5pc2gsXG5cblx0XHRzb3J0OiBzb3J0XG5cdH07XG5cbn1cblxuZnVuY3Rpb24gV2ViR0xSZW5kZXJMaXN0cygpIHtcblxuXHR2YXIgbGlzdHMgPSB7fTtcblxuXHRmdW5jdGlvbiBnZXQoIHNjZW5lLCBjYW1lcmEgKSB7XG5cblx0XHR2YXIgaGFzaCA9IHNjZW5lLmlkICsgJywnICsgY2FtZXJhLmlkO1xuXHRcdHZhciBsaXN0ID0gbGlzdHNbIGhhc2ggXTtcblxuXHRcdGlmICggbGlzdCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHQvLyBjb25zb2xlLmxvZyggJ1RIUkVFLldlYkdMUmVuZGVyTGlzdHM6JywgaGFzaCApO1xuXG5cdFx0XHRsaXN0ID0gbmV3IFdlYkdMUmVuZGVyTGlzdCgpO1xuXHRcdFx0bGlzdHNbIGhhc2ggXSA9IGxpc3Q7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gbGlzdDtcblxuXHR9XG5cblx0ZnVuY3Rpb24gZGlzcG9zZSgpIHtcblxuXHRcdGxpc3RzID0ge307XG5cblx0fVxuXG5cdHJldHVybiB7XG5cdFx0Z2V0OiBnZXQsXG5cdFx0ZGlzcG9zZTogZGlzcG9zZVxuXHR9O1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTEluZGV4ZWRCdWZmZXJSZW5kZXJlciggZ2wsIGV4dGVuc2lvbnMsIGluZm9SZW5kZXIgKSB7XG5cblx0dmFyIG1vZGU7XG5cblx0ZnVuY3Rpb24gc2V0TW9kZSggdmFsdWUgKSB7XG5cblx0XHRtb2RlID0gdmFsdWU7XG5cblx0fVxuXG5cdHZhciB0eXBlLCBzaXplO1xuXG5cdGZ1bmN0aW9uIHNldEluZGV4KCBpbmRleCApIHtcblxuXHRcdGlmICggaW5kZXguYXJyYXkgaW5zdGFuY2VvZiBVaW50MzJBcnJheSAmJiBleHRlbnNpb25zLmdldCggJ09FU19lbGVtZW50X2luZGV4X3VpbnQnICkgKSB7XG5cblx0XHRcdHR5cGUgPSBnbC5VTlNJR05FRF9JTlQ7XG5cdFx0XHRzaXplID0gNDtcblxuXHRcdH0gZWxzZSBpZiAoIGluZGV4LmFycmF5IGluc3RhbmNlb2YgVWludDE2QXJyYXkgKSB7XG5cblx0XHRcdHR5cGUgPSBnbC5VTlNJR05FRF9TSE9SVDtcblx0XHRcdHNpemUgPSAyO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG5cdFx0XHRzaXplID0gMTtcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVuZGVyKCBzdGFydCwgY291bnQgKSB7XG5cblx0XHRnbC5kcmF3RWxlbWVudHMoIG1vZGUsIGNvdW50LCB0eXBlLCBzdGFydCAqIHNpemUgKTtcblxuXHRcdGluZm9SZW5kZXIuY2FsbHMgKys7XG5cdFx0aW5mb1JlbmRlci52ZXJ0aWNlcyArPSBjb3VudDtcblxuXHRcdGlmICggbW9kZSA9PT0gZ2wuVFJJQU5HTEVTICkgaW5mb1JlbmRlci5mYWNlcyArPSBjb3VudCAvIDM7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHJlbmRlckluc3RhbmNlcyggZ2VvbWV0cnksIHN0YXJ0LCBjb3VudCApIHtcblxuXHRcdHZhciBleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ0FOR0xFX2luc3RhbmNlZF9hcnJheXMnICk7XG5cblx0XHRpZiAoIGV4dGVuc2lvbiA9PT0gbnVsbCApIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLldlYkdMSW5kZXhlZEJ1ZmZlclJlbmRlcmVyOiB1c2luZyBUSFJFRS5JbnN0YW5jZWRCdWZmZXJHZW9tZXRyeSBidXQgaGFyZHdhcmUgZG9lcyBub3Qgc3VwcG9ydCBleHRlbnNpb24gQU5HTEVfaW5zdGFuY2VkX2FycmF5cy4nICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHRleHRlbnNpb24uZHJhd0VsZW1lbnRzSW5zdGFuY2VkQU5HTEUoIG1vZGUsIGNvdW50LCB0eXBlLCBzdGFydCAqIHNpemUsIGdlb21ldHJ5Lm1heEluc3RhbmNlZENvdW50ICk7XG5cblx0XHRpbmZvUmVuZGVyLmNhbGxzICsrO1xuXHRcdGluZm9SZW5kZXIudmVydGljZXMgKz0gY291bnQgKiBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudDtcblxuXHRcdGlmICggbW9kZSA9PT0gZ2wuVFJJQU5HTEVTICkgaW5mb1JlbmRlci5mYWNlcyArPSBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudCAqIGNvdW50IC8gMztcblxuXHR9XG5cblx0Ly9cblxuXHR0aGlzLnNldE1vZGUgPSBzZXRNb2RlO1xuXHR0aGlzLnNldEluZGV4ID0gc2V0SW5kZXg7XG5cdHRoaXMucmVuZGVyID0gcmVuZGVyO1xuXHR0aGlzLnJlbmRlckluc3RhbmNlcyA9IHJlbmRlckluc3RhbmNlcztcblxufVxuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gV2ViR0xCdWZmZXJSZW5kZXJlciggZ2wsIGV4dGVuc2lvbnMsIGluZm9SZW5kZXIgKSB7XG5cblx0dmFyIG1vZGU7XG5cblx0ZnVuY3Rpb24gc2V0TW9kZSggdmFsdWUgKSB7XG5cblx0XHRtb2RlID0gdmFsdWU7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHJlbmRlciggc3RhcnQsIGNvdW50ICkge1xuXG5cdFx0Z2wuZHJhd0FycmF5cyggbW9kZSwgc3RhcnQsIGNvdW50ICk7XG5cblx0XHRpbmZvUmVuZGVyLmNhbGxzICsrO1xuXHRcdGluZm9SZW5kZXIudmVydGljZXMgKz0gY291bnQ7XG5cblx0XHRpZiAoIG1vZGUgPT09IGdsLlRSSUFOR0xFUyApIGluZm9SZW5kZXIuZmFjZXMgKz0gY291bnQgLyAzO1xuXG5cdH1cblxuXHRmdW5jdGlvbiByZW5kZXJJbnN0YW5jZXMoIGdlb21ldHJ5LCBzdGFydCwgY291bnQgKSB7XG5cblx0XHR2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9ucy5nZXQoICdBTkdMRV9pbnN0YW5jZWRfYXJyYXlzJyApO1xuXG5cdFx0aWYgKCBleHRlbnNpb24gPT09IG51bGwgKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5XZWJHTEJ1ZmZlclJlbmRlcmVyOiB1c2luZyBUSFJFRS5JbnN0YW5jZWRCdWZmZXJHZW9tZXRyeSBidXQgaGFyZHdhcmUgZG9lcyBub3Qgc3VwcG9ydCBleHRlbnNpb24gQU5HTEVfaW5zdGFuY2VkX2FycmF5cy4nICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHR2YXIgcG9zaXRpb24gPSBnZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uO1xuXG5cdFx0aWYgKCBwb3NpdGlvbi5pc0ludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlICkge1xuXG5cdFx0XHRjb3VudCA9IHBvc2l0aW9uLmRhdGEuY291bnQ7XG5cblx0XHRcdGV4dGVuc2lvbi5kcmF3QXJyYXlzSW5zdGFuY2VkQU5HTEUoIG1vZGUsIDAsIGNvdW50LCBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0ZXh0ZW5zaW9uLmRyYXdBcnJheXNJbnN0YW5jZWRBTkdMRSggbW9kZSwgc3RhcnQsIGNvdW50LCBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudCApO1xuXG5cdFx0fVxuXG5cdFx0aW5mb1JlbmRlci5jYWxscyArKztcblx0XHRpbmZvUmVuZGVyLnZlcnRpY2VzICs9IGNvdW50ICogZ2VvbWV0cnkubWF4SW5zdGFuY2VkQ291bnQ7XG5cblx0XHRpZiAoIG1vZGUgPT09IGdsLlRSSUFOR0xFUyApIGluZm9SZW5kZXIuZmFjZXMgKz0gZ2VvbWV0cnkubWF4SW5zdGFuY2VkQ291bnQgKiBjb3VudCAvIDM7XG5cblx0fVxuXG5cdC8vXG5cblx0dGhpcy5zZXRNb2RlID0gc2V0TW9kZTtcblx0dGhpcy5yZW5kZXIgPSByZW5kZXI7XG5cdHRoaXMucmVuZGVySW5zdGFuY2VzID0gcmVuZGVySW5zdGFuY2VzO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTEdlb21ldHJpZXMoIGdsLCBhdHRyaWJ1dGVzLCBpbmZvTWVtb3J5ICkge1xuXG5cdHZhciBnZW9tZXRyaWVzID0ge307XG5cdHZhciB3aXJlZnJhbWVBdHRyaWJ1dGVzID0ge307XG5cblx0ZnVuY3Rpb24gb25HZW9tZXRyeURpc3Bvc2UoIGV2ZW50ICkge1xuXG5cdFx0dmFyIGdlb21ldHJ5ID0gZXZlbnQudGFyZ2V0O1xuXHRcdHZhciBidWZmZXJnZW9tZXRyeSA9IGdlb21ldHJpZXNbIGdlb21ldHJ5LmlkIF07XG5cblx0XHRpZiAoIGJ1ZmZlcmdlb21ldHJ5LmluZGV4ICE9PSBudWxsICkge1xuXG5cdFx0XHRhdHRyaWJ1dGVzLnJlbW92ZSggYnVmZmVyZ2VvbWV0cnkuaW5kZXggKTtcblxuXHRcdH1cblxuXHRcdGZvciAoIHZhciBuYW1lIGluIGJ1ZmZlcmdlb21ldHJ5LmF0dHJpYnV0ZXMgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZXMucmVtb3ZlKCBidWZmZXJnZW9tZXRyeS5hdHRyaWJ1dGVzWyBuYW1lIF0gKTtcblxuXHRcdH1cblxuXHRcdGdlb21ldHJ5LnJlbW92ZUV2ZW50TGlzdGVuZXIoICdkaXNwb3NlJywgb25HZW9tZXRyeURpc3Bvc2UgKTtcblxuXHRcdGRlbGV0ZSBnZW9tZXRyaWVzWyBnZW9tZXRyeS5pZCBdO1xuXG5cdFx0Ly8gVE9ETyBSZW1vdmUgZHVwbGljYXRlIGNvZGVcblxuXHRcdHZhciBhdHRyaWJ1dGUgPSB3aXJlZnJhbWVBdHRyaWJ1dGVzWyBnZW9tZXRyeS5pZCBdO1xuXG5cdFx0aWYgKCBhdHRyaWJ1dGUgKSB7XG5cblx0XHRcdGF0dHJpYnV0ZXMucmVtb3ZlKCBhdHRyaWJ1dGUgKTtcblx0XHRcdGRlbGV0ZSB3aXJlZnJhbWVBdHRyaWJ1dGVzWyBnZW9tZXRyeS5pZCBdO1xuXG5cdFx0fVxuXG5cdFx0YXR0cmlidXRlID0gd2lyZWZyYW1lQXR0cmlidXRlc1sgYnVmZmVyZ2VvbWV0cnkuaWQgXTtcblxuXHRcdGlmICggYXR0cmlidXRlICkge1xuXG5cdFx0XHRhdHRyaWJ1dGVzLnJlbW92ZSggYXR0cmlidXRlICk7XG5cdFx0XHRkZWxldGUgd2lyZWZyYW1lQXR0cmlidXRlc1sgYnVmZmVyZ2VvbWV0cnkuaWQgXTtcblxuXHRcdH1cblxuXHRcdC8vXG5cblx0XHRpbmZvTWVtb3J5Lmdlb21ldHJpZXMgLS07XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGdldCggb2JqZWN0LCBnZW9tZXRyeSApIHtcblxuXHRcdHZhciBidWZmZXJnZW9tZXRyeSA9IGdlb21ldHJpZXNbIGdlb21ldHJ5LmlkIF07XG5cblx0XHRpZiAoIGJ1ZmZlcmdlb21ldHJ5ICkgcmV0dXJuIGJ1ZmZlcmdlb21ldHJ5O1xuXG5cdFx0Z2VvbWV0cnkuYWRkRXZlbnRMaXN0ZW5lciggJ2Rpc3Bvc2UnLCBvbkdlb21ldHJ5RGlzcG9zZSApO1xuXG5cdFx0aWYgKCBnZW9tZXRyeS5pc0J1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHRidWZmZXJnZW9tZXRyeSA9IGdlb21ldHJ5O1xuXG5cdFx0fSBlbHNlIGlmICggZ2VvbWV0cnkuaXNHZW9tZXRyeSApIHtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5fYnVmZmVyR2VvbWV0cnkgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRnZW9tZXRyeS5fYnVmZmVyR2VvbWV0cnkgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKS5zZXRGcm9tT2JqZWN0KCBvYmplY3QgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRidWZmZXJnZW9tZXRyeSA9IGdlb21ldHJ5Ll9idWZmZXJHZW9tZXRyeTtcblxuXHRcdH1cblxuXHRcdGdlb21ldHJpZXNbIGdlb21ldHJ5LmlkIF0gPSBidWZmZXJnZW9tZXRyeTtcblxuXHRcdGluZm9NZW1vcnkuZ2VvbWV0cmllcyArKztcblxuXHRcdHJldHVybiBidWZmZXJnZW9tZXRyeTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gdXBkYXRlKCBnZW9tZXRyeSApIHtcblxuXHRcdHZhciBpbmRleCA9IGdlb21ldHJ5LmluZGV4O1xuXHRcdHZhciBnZW9tZXRyeUF0dHJpYnV0ZXMgPSBnZW9tZXRyeS5hdHRyaWJ1dGVzO1xuXG5cdFx0aWYgKCBpbmRleCAhPT0gbnVsbCApIHtcblxuXHRcdFx0YXR0cmlidXRlcy51cGRhdGUoIGluZGV4LCBnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiApO1xuXG5cdFx0fVxuXG5cdFx0Zm9yICggdmFyIG5hbWUgaW4gZ2VvbWV0cnlBdHRyaWJ1dGVzICkge1xuXG5cdFx0XHRhdHRyaWJ1dGVzLnVwZGF0ZSggZ2VvbWV0cnlBdHRyaWJ1dGVzWyBuYW1lIF0sIGdsLkFSUkFZX0JVRkZFUiApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gbW9ycGggdGFyZ2V0c1xuXG5cdFx0dmFyIG1vcnBoQXR0cmlidXRlcyA9IGdlb21ldHJ5Lm1vcnBoQXR0cmlidXRlcztcblxuXHRcdGZvciAoIHZhciBuYW1lIGluIG1vcnBoQXR0cmlidXRlcyApIHtcblxuXHRcdFx0dmFyIGFycmF5ID0gbW9ycGhBdHRyaWJ1dGVzWyBuYW1lIF07XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0YXR0cmlidXRlcy51cGRhdGUoIGFycmF5WyBpIF0sIGdsLkFSUkFZX0JVRkZFUiApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGdldFdpcmVmcmFtZUF0dHJpYnV0ZSggZ2VvbWV0cnkgKSB7XG5cblx0XHR2YXIgYXR0cmlidXRlID0gd2lyZWZyYW1lQXR0cmlidXRlc1sgZ2VvbWV0cnkuaWQgXTtcblxuXHRcdGlmICggYXR0cmlidXRlICkgcmV0dXJuIGF0dHJpYnV0ZTtcblxuXHRcdHZhciBpbmRpY2VzID0gW107XG5cblx0XHR2YXIgZ2VvbWV0cnlJbmRleCA9IGdlb21ldHJ5LmluZGV4O1xuXHRcdHZhciBnZW9tZXRyeUF0dHJpYnV0ZXMgPSBnZW9tZXRyeS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gY29uc29sZS50aW1lKCAnd2lyZWZyYW1lJyApO1xuXG5cdFx0aWYgKCBnZW9tZXRyeUluZGV4ICE9PSBudWxsICkge1xuXG5cdFx0XHR2YXIgYXJyYXkgPSBnZW9tZXRyeUluZGV4LmFycmF5O1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBhcnJheS5sZW5ndGg7IGkgPCBsOyBpICs9IDMgKSB7XG5cblx0XHRcdFx0dmFyIGEgPSBhcnJheVsgaSArIDAgXTtcblx0XHRcdFx0dmFyIGIgPSBhcnJheVsgaSArIDEgXTtcblx0XHRcdFx0dmFyIGMgPSBhcnJheVsgaSArIDIgXTtcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGEsIGIsIGIsIGMsIGMsIGEgKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dmFyIGFycmF5ID0gZ2VvbWV0cnlBdHRyaWJ1dGVzLnBvc2l0aW9uLmFycmF5O1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSAoIGFycmF5Lmxlbmd0aCAvIDMgKSAtIDE7IGkgPCBsOyBpICs9IDMgKSB7XG5cblx0XHRcdFx0dmFyIGEgPSBpICsgMDtcblx0XHRcdFx0dmFyIGIgPSBpICsgMTtcblx0XHRcdFx0dmFyIGMgPSBpICsgMjtcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGEsIGIsIGIsIGMsIGMsIGEgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gY29uc29sZS50aW1lRW5kKCAnd2lyZWZyYW1lJyApO1xuXG5cdFx0YXR0cmlidXRlID0gbmV3ICggYXJyYXlNYXgoIGluZGljZXMgKSA+IDY1NTM1ID8gVWludDMyQnVmZmVyQXR0cmlidXRlIDogVWludDE2QnVmZmVyQXR0cmlidXRlICkoIGluZGljZXMsIDEgKTtcblxuXHRcdGF0dHJpYnV0ZXMudXBkYXRlKCBhdHRyaWJ1dGUsIGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSICk7XG5cblx0XHR3aXJlZnJhbWVBdHRyaWJ1dGVzWyBnZW9tZXRyeS5pZCBdID0gYXR0cmlidXRlO1xuXG5cdFx0cmV0dXJuIGF0dHJpYnV0ZTtcblxuXHR9XG5cblx0cmV0dXJuIHtcblxuXHRcdGdldDogZ2V0LFxuXHRcdHVwZGF0ZTogdXBkYXRlLFxuXG5cdFx0Z2V0V2lyZWZyYW1lQXR0cmlidXRlOiBnZXRXaXJlZnJhbWVBdHRyaWJ1dGVcblxuXHR9O1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTExpZ2h0cygpIHtcblxuXHR2YXIgbGlnaHRzID0ge307XG5cblx0cmV0dXJuIHtcblxuXHRcdGdldDogZnVuY3Rpb24gKCBsaWdodCApIHtcblxuXHRcdFx0aWYgKCBsaWdodHNbIGxpZ2h0LmlkIF0gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gbGlnaHRzWyBsaWdodC5pZCBdO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciB1bmlmb3JtcztcblxuXHRcdFx0c3dpdGNoICggbGlnaHQudHlwZSApIHtcblxuXHRcdFx0XHRjYXNlICdEaXJlY3Rpb25hbExpZ2h0Jzpcblx0XHRcdFx0XHR1bmlmb3JtcyA9IHtcblx0XHRcdFx0XHRcdGRpcmVjdGlvbjogbmV3IFZlY3RvcjMoKSxcblx0XHRcdFx0XHRcdGNvbG9yOiBuZXcgQ29sb3IoKSxcblxuXHRcdFx0XHRcdFx0c2hhZG93OiBmYWxzZSxcblx0XHRcdFx0XHRcdHNoYWRvd0JpYXM6IDAsXG5cdFx0XHRcdFx0XHRzaGFkb3dSYWRpdXM6IDEsXG5cdFx0XHRcdFx0XHRzaGFkb3dNYXBTaXplOiBuZXcgVmVjdG9yMigpXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdTcG90TGlnaHQnOlxuXHRcdFx0XHRcdHVuaWZvcm1zID0ge1xuXHRcdFx0XHRcdFx0cG9zaXRpb246IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRkaXJlY3Rpb246IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRjb2xvcjogbmV3IENvbG9yKCksXG5cdFx0XHRcdFx0XHRkaXN0YW5jZTogMCxcblx0XHRcdFx0XHRcdGNvbmVDb3M6IDAsXG5cdFx0XHRcdFx0XHRwZW51bWJyYUNvczogMCxcblx0XHRcdFx0XHRcdGRlY2F5OiAwLFxuXG5cdFx0XHRcdFx0XHRzaGFkb3c6IGZhbHNlLFxuXHRcdFx0XHRcdFx0c2hhZG93QmlhczogMCxcblx0XHRcdFx0XHRcdHNoYWRvd1JhZGl1czogMSxcblx0XHRcdFx0XHRcdHNoYWRvd01hcFNpemU6IG5ldyBWZWN0b3IyKClcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1BvaW50TGlnaHQnOlxuXHRcdFx0XHRcdHVuaWZvcm1zID0ge1xuXHRcdFx0XHRcdFx0cG9zaXRpb246IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRjb2xvcjogbmV3IENvbG9yKCksXG5cdFx0XHRcdFx0XHRkaXN0YW5jZTogMCxcblx0XHRcdFx0XHRcdGRlY2F5OiAwLFxuXG5cdFx0XHRcdFx0XHRzaGFkb3c6IGZhbHNlLFxuXHRcdFx0XHRcdFx0c2hhZG93QmlhczogMCxcblx0XHRcdFx0XHRcdHNoYWRvd1JhZGl1czogMSxcblx0XHRcdFx0XHRcdHNoYWRvd01hcFNpemU6IG5ldyBWZWN0b3IyKClcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ0hlbWlzcGhlcmVMaWdodCc6XG5cdFx0XHRcdFx0dW5pZm9ybXMgPSB7XG5cdFx0XHRcdFx0XHRkaXJlY3Rpb246IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRza3lDb2xvcjogbmV3IENvbG9yKCksXG5cdFx0XHRcdFx0XHRncm91bmRDb2xvcjogbmV3IENvbG9yKClcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1JlY3RBcmVhTGlnaHQnOlxuXHRcdFx0XHRcdHVuaWZvcm1zID0ge1xuXHRcdFx0XHRcdFx0Y29sb3I6IG5ldyBDb2xvcigpLFxuXHRcdFx0XHRcdFx0cG9zaXRpb246IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRoYWxmV2lkdGg6IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRcdFx0XHRoYWxmSGVpZ2h0OiBuZXcgVmVjdG9yMygpXG5cdFx0XHRcdFx0XHQvLyBUT0RPIChhYmVsbmF0aW9uKTogc2V0IFJlY3RBcmVhTGlnaHQgc2hhZG93IHVuaWZvcm1zXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0fVxuXG5cdFx0XHRsaWdodHNbIGxpZ2h0LmlkIF0gPSB1bmlmb3JtcztcblxuXHRcdFx0cmV0dXJuIHVuaWZvcm1zO1xuXG5cdFx0fVxuXG5cdH07XG5cbn1cblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFdlYkdMT2JqZWN0cyggZ2wsIGdlb21ldHJpZXMsIGluZm9SZW5kZXIgKSB7XG5cblx0dmFyIHVwZGF0ZUxpc3QgPSB7fTtcblxuXHRmdW5jdGlvbiB1cGRhdGUoIG9iamVjdCApIHtcblxuXHRcdHZhciBmcmFtZSA9IGluZm9SZW5kZXIuZnJhbWU7XG5cblx0XHR2YXIgZ2VvbWV0cnkgPSBvYmplY3QuZ2VvbWV0cnk7XG5cdFx0dmFyIGJ1ZmZlcmdlb21ldHJ5ID0gZ2VvbWV0cmllcy5nZXQoIG9iamVjdCwgZ2VvbWV0cnkgKTtcblxuXHRcdC8vIFVwZGF0ZSBvbmNlIHBlciBmcmFtZVxuXG5cdFx0aWYgKCB1cGRhdGVMaXN0WyBidWZmZXJnZW9tZXRyeS5pZCBdICE9PSBmcmFtZSApIHtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5pc0dlb21ldHJ5ICkge1xuXG5cdFx0XHRcdGJ1ZmZlcmdlb21ldHJ5LnVwZGF0ZUZyb21PYmplY3QoIG9iamVjdCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGdlb21ldHJpZXMudXBkYXRlKCBidWZmZXJnZW9tZXRyeSApO1xuXG5cdFx0XHR1cGRhdGVMaXN0WyBidWZmZXJnZW9tZXRyeS5pZCBdID0gZnJhbWU7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gYnVmZmVyZ2VvbWV0cnk7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGNsZWFyKCkge1xuXG5cdFx0dXBkYXRlTGlzdCA9IHt9O1xuXG5cdH1cblxuXHRyZXR1cm4ge1xuXG5cdFx0dXBkYXRlOiB1cGRhdGUsXG5cdFx0Y2xlYXI6IGNsZWFyXG5cblx0fTtcblxufVxuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gYWRkTGluZU51bWJlcnMoIHN0cmluZyApIHtcblxuXHR2YXIgbGluZXMgPSBzdHJpbmcuc3BsaXQoICdcXG4nICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0bGluZXNbIGkgXSA9ICggaSArIDEgKSArICc6ICcgKyBsaW5lc1sgaSBdO1xuXG5cdH1cblxuXHRyZXR1cm4gbGluZXMuam9pbiggJ1xcbicgKTtcblxufVxuXG5mdW5jdGlvbiBXZWJHTFNoYWRlciggZ2wsIHR5cGUsIHN0cmluZyApIHtcblxuXHR2YXIgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKCB0eXBlICk7XG5cblx0Z2wuc2hhZGVyU291cmNlKCBzaGFkZXIsIHN0cmluZyApO1xuXHRnbC5jb21waWxlU2hhZGVyKCBzaGFkZXIgKTtcblxuXHRpZiAoIGdsLmdldFNoYWRlclBhcmFtZXRlciggc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUyApID09PSBmYWxzZSApIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5XZWJHTFNoYWRlcjogU2hhZGVyIGNvdWxkblxcJ3QgY29tcGlsZS4nICk7XG5cblx0fVxuXG5cdGlmICggZ2wuZ2V0U2hhZGVySW5mb0xvZyggc2hhZGVyICkgIT09ICcnICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xTaGFkZXI6IGdsLmdldFNoYWRlckluZm9Mb2coKScsIHR5cGUgPT09IGdsLlZFUlRFWF9TSEFERVIgPyAndmVydGV4JyA6ICdmcmFnbWVudCcsIGdsLmdldFNoYWRlckluZm9Mb2coIHNoYWRlciApLCBhZGRMaW5lTnVtYmVycyggc3RyaW5nICkgKTtcblxuXHR9XG5cblx0Ly8gLS1lbmFibGUtcHJpdmlsZWdlZC13ZWJnbC1leHRlbnNpb25cblx0Ly8gY29uc29sZS5sb2coIHR5cGUsIGdsLmdldEV4dGVuc2lvbiggJ1dFQkdMX2RlYnVnX3NoYWRlcnMnICkuZ2V0VHJhbnNsYXRlZFNoYWRlclNvdXJjZSggc2hhZGVyICkgKTtcblxuXHRyZXR1cm4gc2hhZGVyO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG52YXIgcHJvZ3JhbUlkQ291bnQgPSAwO1xuXG5mdW5jdGlvbiBnZXRFbmNvZGluZ0NvbXBvbmVudHMoIGVuY29kaW5nICkge1xuXG5cdHN3aXRjaCAoIGVuY29kaW5nICkge1xuXG5cdFx0Y2FzZSBMaW5lYXJFbmNvZGluZzpcblx0XHRcdHJldHVybiBbICdMaW5lYXInLCcoIHZhbHVlICknIF07XG5cdFx0Y2FzZSBzUkdCRW5jb2Rpbmc6XG5cdFx0XHRyZXR1cm4gWyAnc1JHQicsJyggdmFsdWUgKScgXTtcblx0XHRjYXNlIFJHQkVFbmNvZGluZzpcblx0XHRcdHJldHVybiBbICdSR0JFJywnKCB2YWx1ZSApJyBdO1xuXHRcdGNhc2UgUkdCTTdFbmNvZGluZzpcblx0XHRcdHJldHVybiBbICdSR0JNJywnKCB2YWx1ZSwgNy4wICknIF07XG5cdFx0Y2FzZSBSR0JNMTZFbmNvZGluZzpcblx0XHRcdHJldHVybiBbICdSR0JNJywnKCB2YWx1ZSwgMTYuMCApJyBdO1xuXHRcdGNhc2UgUkdCREVuY29kaW5nOlxuXHRcdFx0cmV0dXJuIFsgJ1JHQkQnLCcoIHZhbHVlLCAyNTYuMCApJyBdO1xuXHRcdGNhc2UgR2FtbWFFbmNvZGluZzpcblx0XHRcdHJldHVybiBbICdHYW1tYScsJyggdmFsdWUsIGZsb2F0KCBHQU1NQV9GQUNUT1IgKSApJyBdO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoICd1bnN1cHBvcnRlZCBlbmNvZGluZzogJyArIGVuY29kaW5nICk7XG5cblx0fVxuXG59XG5cbmZ1bmN0aW9uIGdldFRleGVsRGVjb2RpbmdGdW5jdGlvbiggZnVuY3Rpb25OYW1lLCBlbmNvZGluZyApIHtcblxuXHR2YXIgY29tcG9uZW50cyA9IGdldEVuY29kaW5nQ29tcG9uZW50cyggZW5jb2RpbmcgKTtcblx0cmV0dXJuIFwidmVjNCBcIiArIGZ1bmN0aW9uTmFtZSArIFwiKCB2ZWM0IHZhbHVlICkgeyByZXR1cm4gXCIgKyBjb21wb25lbnRzWyAwIF0gKyBcIlRvTGluZWFyXCIgKyBjb21wb25lbnRzWyAxIF0gKyBcIjsgfVwiO1xuXG59XG5cbmZ1bmN0aW9uIGdldFRleGVsRW5jb2RpbmdGdW5jdGlvbiggZnVuY3Rpb25OYW1lLCBlbmNvZGluZyApIHtcblxuXHR2YXIgY29tcG9uZW50cyA9IGdldEVuY29kaW5nQ29tcG9uZW50cyggZW5jb2RpbmcgKTtcblx0cmV0dXJuIFwidmVjNCBcIiArIGZ1bmN0aW9uTmFtZSArIFwiKCB2ZWM0IHZhbHVlICkgeyByZXR1cm4gTGluZWFyVG9cIiArIGNvbXBvbmVudHNbIDAgXSArIGNvbXBvbmVudHNbIDEgXSArIFwiOyB9XCI7XG5cbn1cblxuZnVuY3Rpb24gZ2V0VG9uZU1hcHBpbmdGdW5jdGlvbiggZnVuY3Rpb25OYW1lLCB0b25lTWFwcGluZyApIHtcblxuXHR2YXIgdG9uZU1hcHBpbmdOYW1lO1xuXG5cdHN3aXRjaCAoIHRvbmVNYXBwaW5nICkge1xuXG5cdFx0Y2FzZSBMaW5lYXJUb25lTWFwcGluZzpcblx0XHRcdHRvbmVNYXBwaW5nTmFtZSA9IFwiTGluZWFyXCI7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgUmVpbmhhcmRUb25lTWFwcGluZzpcblx0XHRcdHRvbmVNYXBwaW5nTmFtZSA9IFwiUmVpbmhhcmRcIjtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSBVbmNoYXJ0ZWQyVG9uZU1hcHBpbmc6XG5cdFx0XHR0b25lTWFwcGluZ05hbWUgPSBcIlVuY2hhcnRlZDJcIjtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSBDaW5lb25Ub25lTWFwcGluZzpcblx0XHRcdHRvbmVNYXBwaW5nTmFtZSA9IFwiT3B0aW1pemVkQ2luZW9uXCI7XG5cdFx0XHRicmVhaztcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoICd1bnN1cHBvcnRlZCB0b25lTWFwcGluZzogJyArIHRvbmVNYXBwaW5nICk7XG5cblx0fVxuXG5cdHJldHVybiBcInZlYzMgXCIgKyBmdW5jdGlvbk5hbWUgKyBcIiggdmVjMyBjb2xvciApIHsgcmV0dXJuIFwiICsgdG9uZU1hcHBpbmdOYW1lICsgXCJUb25lTWFwcGluZyggY29sb3IgKTsgfVwiO1xuXG59XG5cbmZ1bmN0aW9uIGdlbmVyYXRlRXh0ZW5zaW9ucyggZXh0ZW5zaW9ucywgcGFyYW1ldGVycywgcmVuZGVyZXJFeHRlbnNpb25zICkge1xuXG5cdGV4dGVuc2lvbnMgPSBleHRlbnNpb25zIHx8IHt9O1xuXG5cdHZhciBjaHVua3MgPSBbXG5cdFx0KCBleHRlbnNpb25zLmRlcml2YXRpdmVzIHx8IHBhcmFtZXRlcnMuZW52TWFwQ3ViZVVWIHx8IHBhcmFtZXRlcnMuYnVtcE1hcCB8fCBwYXJhbWV0ZXJzLm5vcm1hbE1hcCB8fCBwYXJhbWV0ZXJzLmZsYXRTaGFkaW5nICkgPyAnI2V4dGVuc2lvbiBHTF9PRVNfc3RhbmRhcmRfZGVyaXZhdGl2ZXMgOiBlbmFibGUnIDogJycsXG5cdFx0KCBleHRlbnNpb25zLmZyYWdEZXB0aCB8fCBwYXJhbWV0ZXJzLmxvZ2FyaXRobWljRGVwdGhCdWZmZXIgKSAmJiByZW5kZXJlckV4dGVuc2lvbnMuZ2V0KCAnRVhUX2ZyYWdfZGVwdGgnICkgPyAnI2V4dGVuc2lvbiBHTF9FWFRfZnJhZ19kZXB0aCA6IGVuYWJsZScgOiAnJyxcblx0XHQoIGV4dGVuc2lvbnMuZHJhd0J1ZmZlcnMgKSAmJiByZW5kZXJlckV4dGVuc2lvbnMuZ2V0KCAnV0VCR0xfZHJhd19idWZmZXJzJyApID8gJyNleHRlbnNpb24gR0xfRVhUX2RyYXdfYnVmZmVycyA6IHJlcXVpcmUnIDogJycsXG5cdFx0KCBleHRlbnNpb25zLnNoYWRlclRleHR1cmVMT0QgfHwgcGFyYW1ldGVycy5lbnZNYXAgKSAmJiByZW5kZXJlckV4dGVuc2lvbnMuZ2V0KCAnRVhUX3NoYWRlcl90ZXh0dXJlX2xvZCcgKSA/ICcjZXh0ZW5zaW9uIEdMX0VYVF9zaGFkZXJfdGV4dHVyZV9sb2QgOiBlbmFibGUnIDogJydcblx0XTtcblxuXHRyZXR1cm4gY2h1bmtzLmZpbHRlciggZmlsdGVyRW1wdHlMaW5lICkuam9pbiggJ1xcbicgKTtcblxufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZURlZmluZXMoIGRlZmluZXMgKSB7XG5cblx0dmFyIGNodW5rcyA9IFtdO1xuXG5cdGZvciAoIHZhciBuYW1lIGluIGRlZmluZXMgKSB7XG5cblx0XHR2YXIgdmFsdWUgPSBkZWZpbmVzWyBuYW1lIF07XG5cblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIGNvbnRpbnVlO1xuXG5cdFx0Y2h1bmtzLnB1c2goICcjZGVmaW5lICcgKyBuYW1lICsgJyAnICsgdmFsdWUgKTtcblxuXHR9XG5cblx0cmV0dXJuIGNodW5rcy5qb2luKCAnXFxuJyApO1xuXG59XG5cbmZ1bmN0aW9uIGZldGNoQXR0cmlidXRlTG9jYXRpb25zKCBnbCwgcHJvZ3JhbSwgaWRlbnRpZmllcnMgKSB7XG5cblx0dmFyIGF0dHJpYnV0ZXMgPSB7fTtcblxuXHR2YXIgbiA9IGdsLmdldFByb2dyYW1QYXJhbWV0ZXIoIHByb2dyYW0sIGdsLkFDVElWRV9BVFRSSUJVVEVTICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbjsgaSArKyApIHtcblxuXHRcdHZhciBpbmZvID0gZ2wuZ2V0QWN0aXZlQXR0cmliKCBwcm9ncmFtLCBpICk7XG5cdFx0dmFyIG5hbWUgPSBpbmZvLm5hbWU7XG5cblx0XHQvLyBjb25zb2xlLmxvZyhcIlRIUkVFLldlYkdMUHJvZ3JhbTogQUNUSVZFIFZFUlRFWCBBVFRSSUJVVEU6XCIsIG5hbWUsIGkgKTtcblxuXHRcdGF0dHJpYnV0ZXNbIG5hbWUgXSA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKCBwcm9ncmFtLCBuYW1lICk7XG5cblx0fVxuXG5cdHJldHVybiBhdHRyaWJ1dGVzO1xuXG59XG5cbmZ1bmN0aW9uIGZpbHRlckVtcHR5TGluZSggc3RyaW5nICkge1xuXG5cdHJldHVybiBzdHJpbmcgIT09ICcnO1xuXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VMaWdodE51bXMoIHN0cmluZywgcGFyYW1ldGVycyApIHtcblxuXHRyZXR1cm4gc3RyaW5nXG5cdFx0LnJlcGxhY2UoIC9OVU1fRElSX0xJR0hUUy9nLCBwYXJhbWV0ZXJzLm51bURpckxpZ2h0cyApXG5cdFx0LnJlcGxhY2UoIC9OVU1fU1BPVF9MSUdIVFMvZywgcGFyYW1ldGVycy5udW1TcG90TGlnaHRzIClcblx0XHQucmVwbGFjZSggL05VTV9SRUNUX0FSRUFfTElHSFRTL2csIHBhcmFtZXRlcnMubnVtUmVjdEFyZWFMaWdodHMgKVxuXHRcdC5yZXBsYWNlKCAvTlVNX1BPSU5UX0xJR0hUUy9nLCBwYXJhbWV0ZXJzLm51bVBvaW50TGlnaHRzIClcblx0XHQucmVwbGFjZSggL05VTV9IRU1JX0xJR0hUUy9nLCBwYXJhbWV0ZXJzLm51bUhlbWlMaWdodHMgKTtcblxufVxuXG5mdW5jdGlvbiBwYXJzZUluY2x1ZGVzKCBzdHJpbmcgKSB7XG5cblx0dmFyIHBhdHRlcm4gPSAvXlsgXFx0XSojaW5jbHVkZSArPChbXFx3XFxkLl0rKT4vZ207XG5cblx0ZnVuY3Rpb24gcmVwbGFjZSggbWF0Y2gsIGluY2x1ZGUgKSB7XG5cblx0XHR2YXIgcmVwbGFjZSA9IFNoYWRlckNodW5rWyBpbmNsdWRlIF07XG5cblx0XHRpZiAoIHJlcGxhY2UgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCAnQ2FuIG5vdCByZXNvbHZlICNpbmNsdWRlIDwnICsgaW5jbHVkZSArICc+JyApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBhcnNlSW5jbHVkZXMoIHJlcGxhY2UgKTtcblxuXHR9XG5cblx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKCBwYXR0ZXJuLCByZXBsYWNlICk7XG5cbn1cblxuZnVuY3Rpb24gdW5yb2xsTG9vcHMoIHN0cmluZyApIHtcblxuXHR2YXIgcGF0dGVybiA9IC9mb3IgXFwoIGludCBpIFxcPSAoXFxkKylcXDsgaSA8IChcXGQrKVxcOyBpIFxcK1xcKyBcXCkgXFx7KFtcXHNcXFNdKz8pKD89XFx9KVxcfS9nO1xuXG5cdGZ1bmN0aW9uIHJlcGxhY2UoIG1hdGNoLCBzdGFydCwgZW5kLCBzbmlwcGV0ICkge1xuXG5cdFx0dmFyIHVucm9sbCA9ICcnO1xuXG5cdFx0Zm9yICggdmFyIGkgPSBwYXJzZUludCggc3RhcnQgKTsgaSA8IHBhcnNlSW50KCBlbmQgKTsgaSArKyApIHtcblxuXHRcdFx0dW5yb2xsICs9IHNuaXBwZXQucmVwbGFjZSggL1xcWyBpIFxcXS9nLCAnWyAnICsgaSArICcgXScgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB1bnJvbGw7XG5cblx0fVxuXG5cdHJldHVybiBzdHJpbmcucmVwbGFjZSggcGF0dGVybiwgcmVwbGFjZSApO1xuXG59XG5cbmZ1bmN0aW9uIFdlYkdMUHJvZ3JhbSggcmVuZGVyZXIsIGNvZGUsIG1hdGVyaWFsLCBwYXJhbWV0ZXJzICkge1xuXG5cdHZhciBnbCA9IHJlbmRlcmVyLmNvbnRleHQ7XG5cblx0dmFyIGV4dGVuc2lvbnMgPSBtYXRlcmlhbC5leHRlbnNpb25zO1xuXHR2YXIgZGVmaW5lcyA9IG1hdGVyaWFsLmRlZmluZXM7XG5cblx0dmFyIHZlcnRleFNoYWRlciA9IG1hdGVyaWFsLl9fd2ViZ2xTaGFkZXIudmVydGV4U2hhZGVyO1xuXHR2YXIgZnJhZ21lbnRTaGFkZXIgPSBtYXRlcmlhbC5fX3dlYmdsU2hhZGVyLmZyYWdtZW50U2hhZGVyO1xuXG5cdHZhciBzaGFkb3dNYXBUeXBlRGVmaW5lID0gJ1NIQURPV01BUF9UWVBFX0JBU0lDJztcblxuXHRpZiAoIHBhcmFtZXRlcnMuc2hhZG93TWFwVHlwZSA9PT0gUENGU2hhZG93TWFwICkge1xuXG5cdFx0c2hhZG93TWFwVHlwZURlZmluZSA9ICdTSEFET1dNQVBfVFlQRV9QQ0YnO1xuXG5cdH0gZWxzZSBpZiAoIHBhcmFtZXRlcnMuc2hhZG93TWFwVHlwZSA9PT0gUENGU29mdFNoYWRvd01hcCApIHtcblxuXHRcdHNoYWRvd01hcFR5cGVEZWZpbmUgPSAnU0hBRE9XTUFQX1RZUEVfUENGX1NPRlQnO1xuXG5cdH1cblxuXHR2YXIgZW52TWFwVHlwZURlZmluZSA9ICdFTlZNQVBfVFlQRV9DVUJFJztcblx0dmFyIGVudk1hcE1vZGVEZWZpbmUgPSAnRU5WTUFQX01PREVfUkVGTEVDVElPTic7XG5cdHZhciBlbnZNYXBCbGVuZGluZ0RlZmluZSA9ICdFTlZNQVBfQkxFTkRJTkdfTVVMVElQTFknO1xuXG5cdGlmICggcGFyYW1ldGVycy5lbnZNYXAgKSB7XG5cblx0XHRzd2l0Y2ggKCBtYXRlcmlhbC5lbnZNYXAubWFwcGluZyApIHtcblxuXHRcdFx0Y2FzZSBDdWJlUmVmbGVjdGlvbk1hcHBpbmc6XG5cdFx0XHRjYXNlIEN1YmVSZWZyYWN0aW9uTWFwcGluZzpcblx0XHRcdFx0ZW52TWFwVHlwZURlZmluZSA9ICdFTlZNQVBfVFlQRV9DVUJFJztcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgQ3ViZVVWUmVmbGVjdGlvbk1hcHBpbmc6XG5cdFx0XHRjYXNlIEN1YmVVVlJlZnJhY3Rpb25NYXBwaW5nOlxuXHRcdFx0XHRlbnZNYXBUeXBlRGVmaW5lID0gJ0VOVk1BUF9UWVBFX0NVQkVfVVYnO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBFcXVpcmVjdGFuZ3VsYXJSZWZsZWN0aW9uTWFwcGluZzpcblx0XHRcdGNhc2UgRXF1aXJlY3Rhbmd1bGFyUmVmcmFjdGlvbk1hcHBpbmc6XG5cdFx0XHRcdGVudk1hcFR5cGVEZWZpbmUgPSAnRU5WTUFQX1RZUEVfRVFVSVJFQyc7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIFNwaGVyaWNhbFJlZmxlY3Rpb25NYXBwaW5nOlxuXHRcdFx0XHRlbnZNYXBUeXBlRGVmaW5lID0gJ0VOVk1BUF9UWVBFX1NQSEVSRSc7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0fVxuXG5cdFx0c3dpdGNoICggbWF0ZXJpYWwuZW52TWFwLm1hcHBpbmcgKSB7XG5cblx0XHRcdGNhc2UgQ3ViZVJlZnJhY3Rpb25NYXBwaW5nOlxuXHRcdFx0Y2FzZSBFcXVpcmVjdGFuZ3VsYXJSZWZyYWN0aW9uTWFwcGluZzpcblx0XHRcdFx0ZW52TWFwTW9kZURlZmluZSA9ICdFTlZNQVBfTU9ERV9SRUZSQUNUSU9OJztcblx0XHRcdFx0YnJlYWs7XG5cblx0XHR9XG5cblx0XHRzd2l0Y2ggKCBtYXRlcmlhbC5jb21iaW5lICkge1xuXG5cdFx0XHRjYXNlIE11bHRpcGx5T3BlcmF0aW9uOlxuXHRcdFx0XHRlbnZNYXBCbGVuZGluZ0RlZmluZSA9ICdFTlZNQVBfQkxFTkRJTkdfTVVMVElQTFknO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBNaXhPcGVyYXRpb246XG5cdFx0XHRcdGVudk1hcEJsZW5kaW5nRGVmaW5lID0gJ0VOVk1BUF9CTEVORElOR19NSVgnO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBBZGRPcGVyYXRpb246XG5cdFx0XHRcdGVudk1hcEJsZW5kaW5nRGVmaW5lID0gJ0VOVk1BUF9CTEVORElOR19BREQnO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdH1cblxuXHR9XG5cblx0dmFyIGdhbW1hRmFjdG9yRGVmaW5lID0gKCByZW5kZXJlci5nYW1tYUZhY3RvciA+IDAgKSA/IHJlbmRlcmVyLmdhbW1hRmFjdG9yIDogMS4wO1xuXG5cdC8vIGNvbnNvbGUubG9nKCAnYnVpbGRpbmcgbmV3IHByb2dyYW0gJyApO1xuXG5cdC8vXG5cblx0dmFyIGN1c3RvbUV4dGVuc2lvbnMgPSBnZW5lcmF0ZUV4dGVuc2lvbnMoIGV4dGVuc2lvbnMsIHBhcmFtZXRlcnMsIHJlbmRlcmVyLmV4dGVuc2lvbnMgKTtcblxuXHR2YXIgY3VzdG9tRGVmaW5lcyA9IGdlbmVyYXRlRGVmaW5lcyggZGVmaW5lcyApO1xuXG5cdC8vXG5cblx0dmFyIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG5cblx0dmFyIHByZWZpeFZlcnRleCwgcHJlZml4RnJhZ21lbnQ7XG5cblx0aWYgKCBtYXRlcmlhbC5pc1Jhd1NoYWRlck1hdGVyaWFsICkge1xuXG5cdFx0cHJlZml4VmVydGV4ID0gW1xuXG5cdFx0XHRjdXN0b21EZWZpbmVzLFxuXG5cdFx0XHQnXFxuJ1xuXG5cdFx0XS5maWx0ZXIoIGZpbHRlckVtcHR5TGluZSApLmpvaW4oICdcXG4nICk7XG5cblx0XHRwcmVmaXhGcmFnbWVudCA9IFtcblxuXHRcdFx0Y3VzdG9tRXh0ZW5zaW9ucyxcblx0XHRcdGN1c3RvbURlZmluZXMsXG5cblx0XHRcdCdcXG4nXG5cblx0XHRdLmZpbHRlciggZmlsdGVyRW1wdHlMaW5lICkuam9pbiggJ1xcbicgKTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0cHJlZml4VmVydGV4ID0gW1xuXG5cdFx0XHQncHJlY2lzaW9uICcgKyBwYXJhbWV0ZXJzLnByZWNpc2lvbiArICcgZmxvYXQ7Jyxcblx0XHRcdCdwcmVjaXNpb24gJyArIHBhcmFtZXRlcnMucHJlY2lzaW9uICsgJyBpbnQ7JyxcblxuXHRcdFx0JyNkZWZpbmUgU0hBREVSX05BTUUgJyArIG1hdGVyaWFsLl9fd2ViZ2xTaGFkZXIubmFtZSxcblxuXHRcdFx0Y3VzdG9tRGVmaW5lcyxcblxuXHRcdFx0cGFyYW1ldGVycy5zdXBwb3J0c1ZlcnRleFRleHR1cmVzID8gJyNkZWZpbmUgVkVSVEVYX1RFWFRVUkVTJyA6ICcnLFxuXG5cdFx0XHQnI2RlZmluZSBHQU1NQV9GQUNUT1IgJyArIGdhbW1hRmFjdG9yRGVmaW5lLFxuXG5cdFx0XHQnI2RlZmluZSBNQVhfQk9ORVMgJyArIHBhcmFtZXRlcnMubWF4Qm9uZXMsXG5cdFx0XHQoIHBhcmFtZXRlcnMudXNlRm9nICYmIHBhcmFtZXRlcnMuZm9nICkgPyAnI2RlZmluZSBVU0VfRk9HJyA6ICcnLFxuXHRcdFx0KCBwYXJhbWV0ZXJzLnVzZUZvZyAmJiBwYXJhbWV0ZXJzLmZvZ0V4cCApID8gJyNkZWZpbmUgRk9HX0VYUDInIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMubWFwID8gJyNkZWZpbmUgVVNFX01BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgVVNFX0VOVk1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgJyArIGVudk1hcE1vZGVEZWZpbmUgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMubGlnaHRNYXAgPyAnI2RlZmluZSBVU0VfTElHSFRNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmFvTWFwID8gJyNkZWZpbmUgVVNFX0FPTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5lbWlzc2l2ZU1hcCA/ICcjZGVmaW5lIFVTRV9FTUlTU0lWRU1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuYnVtcE1hcCA/ICcjZGVmaW5lIFVTRV9CVU1QTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5ub3JtYWxNYXAgPyAnI2RlZmluZSBVU0VfTk9STUFMTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5kaXNwbGFjZW1lbnRNYXAgJiYgcGFyYW1ldGVycy5zdXBwb3J0c1ZlcnRleFRleHR1cmVzID8gJyNkZWZpbmUgVVNFX0RJU1BMQUNFTUVOVE1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuc3BlY3VsYXJNYXAgPyAnI2RlZmluZSBVU0VfU1BFQ1VMQVJNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLnJvdWdobmVzc01hcCA/ICcjZGVmaW5lIFVTRV9ST1VHSE5FU1NNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLm1ldGFsbmVzc01hcCA/ICcjZGVmaW5lIFVTRV9NRVRBTE5FU1NNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmFscGhhTWFwID8gJyNkZWZpbmUgVVNFX0FMUEhBTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy52ZXJ0ZXhDb2xvcnMgPyAnI2RlZmluZSBVU0VfQ09MT1InIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMuZmxhdFNoYWRpbmcgPyAnI2RlZmluZSBGTEFUX1NIQURFRCcgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5za2lubmluZyA/ICcjZGVmaW5lIFVTRV9TS0lOTklORycgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMudXNlVmVydGV4VGV4dHVyZSA/ICcjZGVmaW5lIEJPTkVfVEVYVFVSRScgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5tb3JwaFRhcmdldHMgPyAnI2RlZmluZSBVU0VfTU9SUEhUQVJHRVRTJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5tb3JwaE5vcm1hbHMgJiYgcGFyYW1ldGVycy5mbGF0U2hhZGluZyA9PT0gZmFsc2UgPyAnI2RlZmluZSBVU0VfTU9SUEhOT1JNQUxTJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5kb3VibGVTaWRlZCA/ICcjZGVmaW5lIERPVUJMRV9TSURFRCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZmxpcFNpZGVkID8gJyNkZWZpbmUgRkxJUF9TSURFRCcgOiAnJyxcblxuXHRcdFx0JyNkZWZpbmUgTlVNX0NMSVBQSU5HX1BMQU5FUyAnICsgcGFyYW1ldGVycy5udW1DbGlwcGluZ1BsYW5lcyxcblxuXHRcdFx0cGFyYW1ldGVycy5zaGFkb3dNYXBFbmFibGVkID8gJyNkZWZpbmUgVVNFX1NIQURPV01BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuc2hhZG93TWFwRW5hYmxlZCA/ICcjZGVmaW5lICcgKyBzaGFkb3dNYXBUeXBlRGVmaW5lIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMuc2l6ZUF0dGVudWF0aW9uID8gJyNkZWZpbmUgVVNFX1NJWkVBVFRFTlVBVElPTicgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5sb2dhcml0aG1pY0RlcHRoQnVmZmVyID8gJyNkZWZpbmUgVVNFX0xPR0RFUFRIQlVGJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5sb2dhcml0aG1pY0RlcHRoQnVmZmVyICYmIHJlbmRlcmVyLmV4dGVuc2lvbnMuZ2V0KCAnRVhUX2ZyYWdfZGVwdGgnICkgPyAnI2RlZmluZSBVU0VfTE9HREVQVEhCVUZfRVhUJyA6ICcnLFxuXG5cdFx0XHQndW5pZm9ybSBtYXQ0IG1vZGVsTWF0cml4OycsXG5cdFx0XHQndW5pZm9ybSBtYXQ0IG1vZGVsVmlld01hdHJpeDsnLFxuXHRcdFx0J3VuaWZvcm0gbWF0NCBwcm9qZWN0aW9uTWF0cml4OycsXG5cdFx0XHQndW5pZm9ybSBtYXQ0IHZpZXdNYXRyaXg7Jyxcblx0XHRcdCd1bmlmb3JtIG1hdDMgbm9ybWFsTWF0cml4OycsXG5cdFx0XHQndW5pZm9ybSB2ZWMzIGNhbWVyYVBvc2l0aW9uOycsXG5cblx0XHRcdCdhdHRyaWJ1dGUgdmVjMyBwb3NpdGlvbjsnLFxuXHRcdFx0J2F0dHJpYnV0ZSB2ZWMzIG5vcm1hbDsnLFxuXHRcdFx0J2F0dHJpYnV0ZSB2ZWMyIHV2OycsXG5cblx0XHRcdCcjaWZkZWYgVVNFX0NPTE9SJyxcblxuXHRcdFx0J1x0YXR0cmlidXRlIHZlYzMgY29sb3I7JyxcblxuXHRcdFx0JyNlbmRpZicsXG5cblx0XHRcdCcjaWZkZWYgVVNFX01PUlBIVEFSR0VUUycsXG5cblx0XHRcdCdcdGF0dHJpYnV0ZSB2ZWMzIG1vcnBoVGFyZ2V0MDsnLFxuXHRcdFx0J1x0YXR0cmlidXRlIHZlYzMgbW9ycGhUYXJnZXQxOycsXG5cdFx0XHQnXHRhdHRyaWJ1dGUgdmVjMyBtb3JwaFRhcmdldDI7Jyxcblx0XHRcdCdcdGF0dHJpYnV0ZSB2ZWMzIG1vcnBoVGFyZ2V0MzsnLFxuXG5cdFx0XHQnXHQjaWZkZWYgVVNFX01PUlBITk9STUFMUycsXG5cblx0XHRcdCdcdFx0YXR0cmlidXRlIHZlYzMgbW9ycGhOb3JtYWwwOycsXG5cdFx0XHQnXHRcdGF0dHJpYnV0ZSB2ZWMzIG1vcnBoTm9ybWFsMTsnLFxuXHRcdFx0J1x0XHRhdHRyaWJ1dGUgdmVjMyBtb3JwaE5vcm1hbDI7Jyxcblx0XHRcdCdcdFx0YXR0cmlidXRlIHZlYzMgbW9ycGhOb3JtYWwzOycsXG5cblx0XHRcdCdcdCNlbHNlJyxcblxuXHRcdFx0J1x0XHRhdHRyaWJ1dGUgdmVjMyBtb3JwaFRhcmdldDQ7Jyxcblx0XHRcdCdcdFx0YXR0cmlidXRlIHZlYzMgbW9ycGhUYXJnZXQ1OycsXG5cdFx0XHQnXHRcdGF0dHJpYnV0ZSB2ZWMzIG1vcnBoVGFyZ2V0NjsnLFxuXHRcdFx0J1x0XHRhdHRyaWJ1dGUgdmVjMyBtb3JwaFRhcmdldDc7JyxcblxuXHRcdFx0J1x0I2VuZGlmJyxcblxuXHRcdFx0JyNlbmRpZicsXG5cblx0XHRcdCcjaWZkZWYgVVNFX1NLSU5OSU5HJyxcblxuXHRcdFx0J1x0YXR0cmlidXRlIHZlYzQgc2tpbkluZGV4OycsXG5cdFx0XHQnXHRhdHRyaWJ1dGUgdmVjNCBza2luV2VpZ2h0OycsXG5cblx0XHRcdCcjZW5kaWYnLFxuXG5cdFx0XHQnXFxuJ1xuXG5cdFx0XS5maWx0ZXIoIGZpbHRlckVtcHR5TGluZSApLmpvaW4oICdcXG4nICk7XG5cblx0XHRwcmVmaXhGcmFnbWVudCA9IFtcblxuXHRcdFx0Y3VzdG9tRXh0ZW5zaW9ucyxcblxuXHRcdFx0J3ByZWNpc2lvbiAnICsgcGFyYW1ldGVycy5wcmVjaXNpb24gKyAnIGZsb2F0OycsXG5cdFx0XHQncHJlY2lzaW9uICcgKyBwYXJhbWV0ZXJzLnByZWNpc2lvbiArICcgaW50OycsXG5cblx0XHRcdCcjZGVmaW5lIFNIQURFUl9OQU1FICcgKyBtYXRlcmlhbC5fX3dlYmdsU2hhZGVyLm5hbWUsXG5cblx0XHRcdGN1c3RvbURlZmluZXMsXG5cblx0XHRcdHBhcmFtZXRlcnMuYWxwaGFUZXN0ID8gJyNkZWZpbmUgQUxQSEFURVNUICcgKyBwYXJhbWV0ZXJzLmFscGhhVGVzdCA6ICcnLFxuXG5cdFx0XHQnI2RlZmluZSBHQU1NQV9GQUNUT1IgJyArIGdhbW1hRmFjdG9yRGVmaW5lLFxuXG5cdFx0XHQoIHBhcmFtZXRlcnMudXNlRm9nICYmIHBhcmFtZXRlcnMuZm9nICkgPyAnI2RlZmluZSBVU0VfRk9HJyA6ICcnLFxuXHRcdFx0KCBwYXJhbWV0ZXJzLnVzZUZvZyAmJiBwYXJhbWV0ZXJzLmZvZ0V4cCApID8gJyNkZWZpbmUgRk9HX0VYUDInIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMubWFwID8gJyNkZWZpbmUgVVNFX01BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgVVNFX0VOVk1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgJyArIGVudk1hcFR5cGVEZWZpbmUgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgJyArIGVudk1hcE1vZGVEZWZpbmUgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW52TWFwID8gJyNkZWZpbmUgJyArIGVudk1hcEJsZW5kaW5nRGVmaW5lIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmxpZ2h0TWFwID8gJyNkZWZpbmUgVVNFX0xJR0hUTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5hb01hcCA/ICcjZGVmaW5lIFVTRV9BT01BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZW1pc3NpdmVNYXAgPyAnI2RlZmluZSBVU0VfRU1JU1NJVkVNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmJ1bXBNYXAgPyAnI2RlZmluZSBVU0VfQlVNUE1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMubm9ybWFsTWFwID8gJyNkZWZpbmUgVVNFX05PUk1BTE1BUCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuc3BlY3VsYXJNYXAgPyAnI2RlZmluZSBVU0VfU1BFQ1VMQVJNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLnJvdWdobmVzc01hcCA/ICcjZGVmaW5lIFVTRV9ST1VHSE5FU1NNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLm1ldGFsbmVzc01hcCA/ICcjZGVmaW5lIFVTRV9NRVRBTE5FU1NNQVAnIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmFscGhhTWFwID8gJyNkZWZpbmUgVVNFX0FMUEhBTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy52ZXJ0ZXhDb2xvcnMgPyAnI2RlZmluZSBVU0VfQ09MT1InIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMuZ3JhZGllbnRNYXAgPyAnI2RlZmluZSBVU0VfR1JBRElFTlRNQVAnIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMuZmxhdFNoYWRpbmcgPyAnI2RlZmluZSBGTEFUX1NIQURFRCcgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5kb3VibGVTaWRlZCA/ICcjZGVmaW5lIERPVUJMRV9TSURFRCcgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMuZmxpcFNpZGVkID8gJyNkZWZpbmUgRkxJUF9TSURFRCcgOiAnJyxcblxuXHRcdFx0JyNkZWZpbmUgTlVNX0NMSVBQSU5HX1BMQU5FUyAnICsgcGFyYW1ldGVycy5udW1DbGlwcGluZ1BsYW5lcyxcblx0XHRcdCcjZGVmaW5lIFVOSU9OX0NMSVBQSU5HX1BMQU5FUyAnICsgKHBhcmFtZXRlcnMubnVtQ2xpcHBpbmdQbGFuZXMgLSBwYXJhbWV0ZXJzLm51bUNsaXBJbnRlcnNlY3Rpb24pLFxuXG5cdFx0XHRwYXJhbWV0ZXJzLnNoYWRvd01hcEVuYWJsZWQgPyAnI2RlZmluZSBVU0VfU0hBRE9XTUFQJyA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5zaGFkb3dNYXBFbmFibGVkID8gJyNkZWZpbmUgJyArIHNoYWRvd01hcFR5cGVEZWZpbmUgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5wcmVtdWx0aXBsaWVkQWxwaGEgPyBcIiNkZWZpbmUgUFJFTVVMVElQTElFRF9BTFBIQVwiIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMucGh5c2ljYWxseUNvcnJlY3RMaWdodHMgPyBcIiNkZWZpbmUgUEhZU0lDQUxMWV9DT1JSRUNUX0xJR0hUU1wiIDogJycsXG5cblx0XHRcdHBhcmFtZXRlcnMubG9nYXJpdGhtaWNEZXB0aEJ1ZmZlciA/ICcjZGVmaW5lIFVTRV9MT0dERVBUSEJVRicgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMubG9nYXJpdGhtaWNEZXB0aEJ1ZmZlciAmJiByZW5kZXJlci5leHRlbnNpb25zLmdldCggJ0VYVF9mcmFnX2RlcHRoJyApID8gJyNkZWZpbmUgVVNFX0xPR0RFUFRIQlVGX0VYVCcgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5lbnZNYXAgJiYgcmVuZGVyZXIuZXh0ZW5zaW9ucy5nZXQoICdFWFRfc2hhZGVyX3RleHR1cmVfbG9kJyApID8gJyNkZWZpbmUgVEVYVFVSRV9MT0RfRVhUJyA6ICcnLFxuXG5cdFx0XHQndW5pZm9ybSBtYXQ0IHZpZXdNYXRyaXg7Jyxcblx0XHRcdCd1bmlmb3JtIHZlYzMgY2FtZXJhUG9zaXRpb247JyxcblxuXHRcdFx0KCBwYXJhbWV0ZXJzLnRvbmVNYXBwaW5nICE9PSBOb1RvbmVNYXBwaW5nICkgPyBcIiNkZWZpbmUgVE9ORV9NQVBQSU5HXCIgOiAnJyxcblx0XHRcdCggcGFyYW1ldGVycy50b25lTWFwcGluZyAhPT0gTm9Ub25lTWFwcGluZyApID8gU2hhZGVyQ2h1bmtbICd0b25lbWFwcGluZ19wYXJzX2ZyYWdtZW50JyBdIDogJycsICAvLyB0aGlzIGNvZGUgaXMgcmVxdWlyZWQgaGVyZSBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgdGhlIHRvbmVNYXBwaW5nKCkgZnVuY3Rpb24gZGVmaW5lZCBiZWxvd1xuXHRcdFx0KCBwYXJhbWV0ZXJzLnRvbmVNYXBwaW5nICE9PSBOb1RvbmVNYXBwaW5nICkgPyBnZXRUb25lTWFwcGluZ0Z1bmN0aW9uKCBcInRvbmVNYXBwaW5nXCIsIHBhcmFtZXRlcnMudG9uZU1hcHBpbmcgKSA6ICcnLFxuXG5cdFx0XHRwYXJhbWV0ZXJzLmRpdGhlcmluZyA/ICcjZGVmaW5lIERJVEhFUklORycgOiAnJyxcblxuXHRcdFx0KCBwYXJhbWV0ZXJzLm91dHB1dEVuY29kaW5nIHx8IHBhcmFtZXRlcnMubWFwRW5jb2RpbmcgfHwgcGFyYW1ldGVycy5lbnZNYXBFbmNvZGluZyB8fCBwYXJhbWV0ZXJzLmVtaXNzaXZlTWFwRW5jb2RpbmcgKSA/IFNoYWRlckNodW5rWyAnZW5jb2RpbmdzX3BhcnNfZnJhZ21lbnQnIF0gOiAnJywgLy8gdGhpcyBjb2RlIGlzIHJlcXVpcmVkIGhlcmUgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IHRoZSB2YXJpb3VzIGVuY29kaW5nL2RlY29kaW5nIGZ1bmN0aW9uIGRlZmluZWQgYmVsb3dcblx0XHRcdHBhcmFtZXRlcnMubWFwRW5jb2RpbmcgPyBnZXRUZXhlbERlY29kaW5nRnVuY3Rpb24oICdtYXBUZXhlbFRvTGluZWFyJywgcGFyYW1ldGVycy5tYXBFbmNvZGluZyApIDogJycsXG5cdFx0XHRwYXJhbWV0ZXJzLmVudk1hcEVuY29kaW5nID8gZ2V0VGV4ZWxEZWNvZGluZ0Z1bmN0aW9uKCAnZW52TWFwVGV4ZWxUb0xpbmVhcicsIHBhcmFtZXRlcnMuZW52TWFwRW5jb2RpbmcgKSA6ICcnLFxuXHRcdFx0cGFyYW1ldGVycy5lbWlzc2l2ZU1hcEVuY29kaW5nID8gZ2V0VGV4ZWxEZWNvZGluZ0Z1bmN0aW9uKCAnZW1pc3NpdmVNYXBUZXhlbFRvTGluZWFyJywgcGFyYW1ldGVycy5lbWlzc2l2ZU1hcEVuY29kaW5nICkgOiAnJyxcblx0XHRcdHBhcmFtZXRlcnMub3V0cHV0RW5jb2RpbmcgPyBnZXRUZXhlbEVuY29kaW5nRnVuY3Rpb24oIFwibGluZWFyVG9PdXRwdXRUZXhlbFwiLCBwYXJhbWV0ZXJzLm91dHB1dEVuY29kaW5nICkgOiAnJyxcblxuXHRcdFx0cGFyYW1ldGVycy5kZXB0aFBhY2tpbmcgPyBcIiNkZWZpbmUgREVQVEhfUEFDS0lORyBcIiArIG1hdGVyaWFsLmRlcHRoUGFja2luZyA6ICcnLFxuXG5cdFx0XHQnXFxuJ1xuXG5cdFx0XS5maWx0ZXIoIGZpbHRlckVtcHR5TGluZSApLmpvaW4oICdcXG4nICk7XG5cblx0fVxuXG5cdHZlcnRleFNoYWRlciA9IHBhcnNlSW5jbHVkZXMoIHZlcnRleFNoYWRlciwgcGFyYW1ldGVycyApO1xuXHR2ZXJ0ZXhTaGFkZXIgPSByZXBsYWNlTGlnaHROdW1zKCB2ZXJ0ZXhTaGFkZXIsIHBhcmFtZXRlcnMgKTtcblxuXHRmcmFnbWVudFNoYWRlciA9IHBhcnNlSW5jbHVkZXMoIGZyYWdtZW50U2hhZGVyLCBwYXJhbWV0ZXJzICk7XG5cdGZyYWdtZW50U2hhZGVyID0gcmVwbGFjZUxpZ2h0TnVtcyggZnJhZ21lbnRTaGFkZXIsIHBhcmFtZXRlcnMgKTtcblxuXHRpZiAoICEgbWF0ZXJpYWwuaXNTaGFkZXJNYXRlcmlhbCApIHtcblxuXHRcdHZlcnRleFNoYWRlciA9IHVucm9sbExvb3BzKCB2ZXJ0ZXhTaGFkZXIgKTtcblx0XHRmcmFnbWVudFNoYWRlciA9IHVucm9sbExvb3BzKCBmcmFnbWVudFNoYWRlciApO1xuXG5cdH1cblxuXHR2YXIgdmVydGV4R2xzbCA9IHByZWZpeFZlcnRleCArIHZlcnRleFNoYWRlcjtcblx0dmFyIGZyYWdtZW50R2xzbCA9IHByZWZpeEZyYWdtZW50ICsgZnJhZ21lbnRTaGFkZXI7XG5cblx0Ly8gY29uc29sZS5sb2coICcqVkVSVEVYKicsIHZlcnRleEdsc2wgKTtcblx0Ly8gY29uc29sZS5sb2coICcqRlJBR01FTlQqJywgZnJhZ21lbnRHbHNsICk7XG5cblx0dmFyIGdsVmVydGV4U2hhZGVyID0gV2ViR0xTaGFkZXIoIGdsLCBnbC5WRVJURVhfU0hBREVSLCB2ZXJ0ZXhHbHNsICk7XG5cdHZhciBnbEZyYWdtZW50U2hhZGVyID0gV2ViR0xTaGFkZXIoIGdsLCBnbC5GUkFHTUVOVF9TSEFERVIsIGZyYWdtZW50R2xzbCApO1xuXG5cdGdsLmF0dGFjaFNoYWRlciggcHJvZ3JhbSwgZ2xWZXJ0ZXhTaGFkZXIgKTtcblx0Z2wuYXR0YWNoU2hhZGVyKCBwcm9ncmFtLCBnbEZyYWdtZW50U2hhZGVyICk7XG5cblx0Ly8gRm9yY2UgYSBwYXJ0aWN1bGFyIGF0dHJpYnV0ZSB0byBpbmRleCAwLlxuXG5cdGlmICggbWF0ZXJpYWwuaW5kZXgwQXR0cmlidXRlTmFtZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0Z2wuYmluZEF0dHJpYkxvY2F0aW9uKCBwcm9ncmFtLCAwLCBtYXRlcmlhbC5pbmRleDBBdHRyaWJ1dGVOYW1lICk7XG5cblx0fSBlbHNlIGlmICggcGFyYW1ldGVycy5tb3JwaFRhcmdldHMgPT09IHRydWUgKSB7XG5cblx0XHQvLyBwcm9ncmFtcyB3aXRoIG1vcnBoVGFyZ2V0cyBkaXNwbGFjZSBwb3NpdGlvbiBvdXQgb2YgYXR0cmlidXRlIDBcblx0XHRnbC5iaW5kQXR0cmliTG9jYXRpb24oIHByb2dyYW0sIDAsICdwb3NpdGlvbicgKTtcblxuXHR9XG5cblx0Z2wubGlua1Byb2dyYW0oIHByb2dyYW0gKTtcblxuXHR2YXIgcHJvZ3JhbUxvZyA9IGdsLmdldFByb2dyYW1JbmZvTG9nKCBwcm9ncmFtICk7XG5cdHZhciB2ZXJ0ZXhMb2cgPSBnbC5nZXRTaGFkZXJJbmZvTG9nKCBnbFZlcnRleFNoYWRlciApO1xuXHR2YXIgZnJhZ21lbnRMb2cgPSBnbC5nZXRTaGFkZXJJbmZvTG9nKCBnbEZyYWdtZW50U2hhZGVyICk7XG5cblx0dmFyIHJ1bm5hYmxlID0gdHJ1ZTtcblx0dmFyIGhhdmVEaWFnbm9zdGljcyA9IHRydWU7XG5cblx0Ly8gY29uc29sZS5sb2coICcqKlZFUlRFWCoqJywgZ2wuZ2V0RXh0ZW5zaW9uKCAnV0VCR0xfZGVidWdfc2hhZGVycycgKS5nZXRUcmFuc2xhdGVkU2hhZGVyU291cmNlKCBnbFZlcnRleFNoYWRlciApICk7XG5cdC8vIGNvbnNvbGUubG9nKCAnKipGUkFHTUVOVCoqJywgZ2wuZ2V0RXh0ZW5zaW9uKCAnV0VCR0xfZGVidWdfc2hhZGVycycgKS5nZXRUcmFuc2xhdGVkU2hhZGVyU291cmNlKCBnbEZyYWdtZW50U2hhZGVyICkgKTtcblxuXHRpZiAoIGdsLmdldFByb2dyYW1QYXJhbWV0ZXIoIHByb2dyYW0sIGdsLkxJTktfU1RBVFVTICkgPT09IGZhbHNlICkge1xuXG5cdFx0cnVubmFibGUgPSBmYWxzZTtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5XZWJHTFByb2dyYW06IHNoYWRlciBlcnJvcjogJywgZ2wuZ2V0RXJyb3IoKSwgJ2dsLlZBTElEQVRFX1NUQVRVUycsIGdsLmdldFByb2dyYW1QYXJhbWV0ZXIoIHByb2dyYW0sIGdsLlZBTElEQVRFX1NUQVRVUyApLCAnZ2wuZ2V0UHJvZ3JhbUluZm9Mb2cnLCBwcm9ncmFtTG9nLCB2ZXJ0ZXhMb2csIGZyYWdtZW50TG9nICk7XG5cblx0fSBlbHNlIGlmICggcHJvZ3JhbUxvZyAhPT0gJycgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFByb2dyYW06IGdsLmdldFByb2dyYW1JbmZvTG9nKCknLCBwcm9ncmFtTG9nICk7XG5cblx0fSBlbHNlIGlmICggdmVydGV4TG9nID09PSAnJyB8fCBmcmFnbWVudExvZyA9PT0gJycgKSB7XG5cblx0XHRoYXZlRGlhZ25vc3RpY3MgPSBmYWxzZTtcblxuXHR9XG5cblx0aWYgKCBoYXZlRGlhZ25vc3RpY3MgKSB7XG5cblx0XHR0aGlzLmRpYWdub3N0aWNzID0ge1xuXG5cdFx0XHRydW5uYWJsZTogcnVubmFibGUsXG5cdFx0XHRtYXRlcmlhbDogbWF0ZXJpYWwsXG5cblx0XHRcdHByb2dyYW1Mb2c6IHByb2dyYW1Mb2csXG5cblx0XHRcdHZlcnRleFNoYWRlcjoge1xuXG5cdFx0XHRcdGxvZzogdmVydGV4TG9nLFxuXHRcdFx0XHRwcmVmaXg6IHByZWZpeFZlcnRleFxuXG5cdFx0XHR9LFxuXG5cdFx0XHRmcmFnbWVudFNoYWRlcjoge1xuXG5cdFx0XHRcdGxvZzogZnJhZ21lbnRMb2csXG5cdFx0XHRcdHByZWZpeDogcHJlZml4RnJhZ21lbnRcblxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHR9XG5cblx0Ly8gY2xlYW4gdXBcblxuXHRnbC5kZWxldGVTaGFkZXIoIGdsVmVydGV4U2hhZGVyICk7XG5cdGdsLmRlbGV0ZVNoYWRlciggZ2xGcmFnbWVudFNoYWRlciApO1xuXG5cdC8vIHNldCB1cCBjYWNoaW5nIGZvciB1bmlmb3JtIGxvY2F0aW9uc1xuXG5cdHZhciBjYWNoZWRVbmlmb3JtcztcblxuXHR0aGlzLmdldFVuaWZvcm1zID0gZnVuY3Rpb24oKSB7XG5cblx0XHRpZiAoIGNhY2hlZFVuaWZvcm1zID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNhY2hlZFVuaWZvcm1zID1cblx0XHRcdFx0bmV3IFdlYkdMVW5pZm9ybXMoIGdsLCBwcm9ncmFtLCByZW5kZXJlciApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNhY2hlZFVuaWZvcm1zO1xuXG5cdH07XG5cblx0Ly8gc2V0IHVwIGNhY2hpbmcgZm9yIGF0dHJpYnV0ZSBsb2NhdGlvbnNcblxuXHR2YXIgY2FjaGVkQXR0cmlidXRlcztcblxuXHR0aGlzLmdldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbigpIHtcblxuXHRcdGlmICggY2FjaGVkQXR0cmlidXRlcyA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjYWNoZWRBdHRyaWJ1dGVzID0gZmV0Y2hBdHRyaWJ1dGVMb2NhdGlvbnMoIGdsLCBwcm9ncmFtICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gY2FjaGVkQXR0cmlidXRlcztcblxuXHR9O1xuXG5cdC8vIGZyZWUgcmVzb3VyY2VcblxuXHR0aGlzLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcblxuXHRcdGdsLmRlbGV0ZVByb2dyYW0oIHByb2dyYW0gKTtcblx0XHR0aGlzLnByb2dyYW0gPSB1bmRlZmluZWQ7XG5cblx0fTtcblxuXHQvLyBERVBSRUNBVEVEXG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIHRoaXMsIHtcblxuXHRcdHVuaWZvcm1zOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUHJvZ3JhbTogLnVuaWZvcm1zIGlzIG5vdyAuZ2V0VW5pZm9ybXMoKS4nICk7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFVuaWZvcm1zKCk7XG5cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0YXR0cmlidXRlczoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFByb2dyYW06IC5hdHRyaWJ1dGVzIGlzIG5vdyAuZ2V0QXR0cmlidXRlcygpLicgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlcygpO1xuXG5cdFx0XHR9XG5cdFx0fVxuXG5cdH0gKTtcblxuXG5cdC8vXG5cblx0dGhpcy5pZCA9IHByb2dyYW1JZENvdW50ICsrO1xuXHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR0aGlzLnVzZWRUaW1lcyA9IDE7XG5cdHRoaXMucHJvZ3JhbSA9IHByb2dyYW07XG5cdHRoaXMudmVydGV4U2hhZGVyID0gZ2xWZXJ0ZXhTaGFkZXI7XG5cdHRoaXMuZnJhZ21lbnRTaGFkZXIgPSBnbEZyYWdtZW50U2hhZGVyO1xuXG5cdHJldHVybiB0aGlzO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTFByb2dyYW1zKCByZW5kZXJlciwgY2FwYWJpbGl0aWVzICkge1xuXG5cdHZhciBwcm9ncmFtcyA9IFtdO1xuXG5cdHZhciBzaGFkZXJJRHMgPSB7XG5cdFx0TWVzaERlcHRoTWF0ZXJpYWw6ICdkZXB0aCcsXG5cdFx0TWVzaE5vcm1hbE1hdGVyaWFsOiAnbm9ybWFsJyxcblx0XHRNZXNoQmFzaWNNYXRlcmlhbDogJ2Jhc2ljJyxcblx0XHRNZXNoTGFtYmVydE1hdGVyaWFsOiAnbGFtYmVydCcsXG5cdFx0TWVzaFBob25nTWF0ZXJpYWw6ICdwaG9uZycsXG5cdFx0TWVzaFRvb25NYXRlcmlhbDogJ3Bob25nJyxcblx0XHRNZXNoU3RhbmRhcmRNYXRlcmlhbDogJ3BoeXNpY2FsJyxcblx0XHRNZXNoUGh5c2ljYWxNYXRlcmlhbDogJ3BoeXNpY2FsJyxcblx0XHRMaW5lQmFzaWNNYXRlcmlhbDogJ2Jhc2ljJyxcblx0XHRMaW5lRGFzaGVkTWF0ZXJpYWw6ICdkYXNoZWQnLFxuXHRcdFBvaW50c01hdGVyaWFsOiAncG9pbnRzJ1xuXHR9O1xuXG5cdHZhciBwYXJhbWV0ZXJOYW1lcyA9IFtcblx0XHRcInByZWNpc2lvblwiLCBcInN1cHBvcnRzVmVydGV4VGV4dHVyZXNcIiwgXCJtYXBcIiwgXCJtYXBFbmNvZGluZ1wiLCBcImVudk1hcFwiLCBcImVudk1hcE1vZGVcIiwgXCJlbnZNYXBFbmNvZGluZ1wiLFxuXHRcdFwibGlnaHRNYXBcIiwgXCJhb01hcFwiLCBcImVtaXNzaXZlTWFwXCIsIFwiZW1pc3NpdmVNYXBFbmNvZGluZ1wiLCBcImJ1bXBNYXBcIiwgXCJub3JtYWxNYXBcIiwgXCJkaXNwbGFjZW1lbnRNYXBcIiwgXCJzcGVjdWxhck1hcFwiLFxuXHRcdFwicm91Z2huZXNzTWFwXCIsIFwibWV0YWxuZXNzTWFwXCIsIFwiZ3JhZGllbnRNYXBcIixcblx0XHRcImFscGhhTWFwXCIsIFwiY29tYmluZVwiLCBcInZlcnRleENvbG9yc1wiLCBcImZvZ1wiLCBcInVzZUZvZ1wiLCBcImZvZ0V4cFwiLFxuXHRcdFwiZmxhdFNoYWRpbmdcIiwgXCJzaXplQXR0ZW51YXRpb25cIiwgXCJsb2dhcml0aG1pY0RlcHRoQnVmZmVyXCIsIFwic2tpbm5pbmdcIixcblx0XHRcIm1heEJvbmVzXCIsIFwidXNlVmVydGV4VGV4dHVyZVwiLCBcIm1vcnBoVGFyZ2V0c1wiLCBcIm1vcnBoTm9ybWFsc1wiLFxuXHRcdFwibWF4TW9ycGhUYXJnZXRzXCIsIFwibWF4TW9ycGhOb3JtYWxzXCIsIFwicHJlbXVsdGlwbGllZEFscGhhXCIsXG5cdFx0XCJudW1EaXJMaWdodHNcIiwgXCJudW1Qb2ludExpZ2h0c1wiLCBcIm51bVNwb3RMaWdodHNcIiwgXCJudW1IZW1pTGlnaHRzXCIsIFwibnVtUmVjdEFyZWFMaWdodHNcIixcblx0XHRcInNoYWRvd01hcEVuYWJsZWRcIiwgXCJzaGFkb3dNYXBUeXBlXCIsIFwidG9uZU1hcHBpbmdcIiwgJ3BoeXNpY2FsbHlDb3JyZWN0TGlnaHRzJyxcblx0XHRcImFscGhhVGVzdFwiLCBcImRvdWJsZVNpZGVkXCIsIFwiZmxpcFNpZGVkXCIsIFwibnVtQ2xpcHBpbmdQbGFuZXNcIiwgXCJudW1DbGlwSW50ZXJzZWN0aW9uXCIsIFwiZGVwdGhQYWNraW5nXCIsIFwiZGl0aGVyaW5nXCJcblx0XTtcblxuXG5cdGZ1bmN0aW9uIGFsbG9jYXRlQm9uZXMoIG9iamVjdCApIHtcblxuXHRcdHZhciBza2VsZXRvbiA9IG9iamVjdC5za2VsZXRvbjtcblx0XHR2YXIgYm9uZXMgPSBza2VsZXRvbi5ib25lcztcblxuXHRcdGlmICggY2FwYWJpbGl0aWVzLmZsb2F0VmVydGV4VGV4dHVyZXMgKSB7XG5cblx0XHRcdHJldHVybiAxMDI0O1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gZGVmYXVsdCBmb3Igd2hlbiBvYmplY3QgaXMgbm90IHNwZWNpZmllZFxuXHRcdFx0Ly8gKCBmb3IgZXhhbXBsZSB3aGVuIHByZWJ1aWxkaW5nIHNoYWRlciB0byBiZSB1c2VkIHdpdGggbXVsdGlwbGUgb2JqZWN0cyApXG5cdFx0XHQvL1xuXHRcdFx0Ly8gIC0gbGVhdmUgc29tZSBleHRyYSBzcGFjZSBmb3Igb3RoZXIgdW5pZm9ybXNcblx0XHRcdC8vICAtIGxpbWl0IGhlcmUgaXMgQU5HTEUncyAyNTQgbWF4IHVuaWZvcm0gdmVjdG9yc1xuXHRcdFx0Ly8gICAgKHVwIHRvIDU0IHNob3VsZCBiZSBzYWZlKVxuXG5cdFx0XHR2YXIgblZlcnRleFVuaWZvcm1zID0gY2FwYWJpbGl0aWVzLm1heFZlcnRleFVuaWZvcm1zO1xuXHRcdFx0dmFyIG5WZXJ0ZXhNYXRyaWNlcyA9IE1hdGguZmxvb3IoICggblZlcnRleFVuaWZvcm1zIC0gMjAgKSAvIDQgKTtcblxuXHRcdFx0dmFyIG1heEJvbmVzID0gTWF0aC5taW4oIG5WZXJ0ZXhNYXRyaWNlcywgYm9uZXMubGVuZ3RoICk7XG5cblx0XHRcdGlmICggbWF4Qm9uZXMgPCBib25lcy5sZW5ndGggKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogU2tlbGV0b24gaGFzICcgKyBib25lcy5sZW5ndGggKyAnIGJvbmVzLiBUaGlzIEdQVSBzdXBwb3J0cyAnICsgbWF4Qm9uZXMgKyAnLicgKTtcblx0XHRcdFx0cmV0dXJuIDA7XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1heEJvbmVzO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBnZXRUZXh0dXJlRW5jb2RpbmdGcm9tTWFwKCBtYXAsIGdhbW1hT3ZlcnJpZGVMaW5lYXIgKSB7XG5cblx0XHR2YXIgZW5jb2Rpbmc7XG5cblx0XHRpZiAoICEgbWFwICkge1xuXG5cdFx0XHRlbmNvZGluZyA9IExpbmVhckVuY29kaW5nO1xuXG5cdFx0fSBlbHNlIGlmICggbWFwLmlzVGV4dHVyZSApIHtcblxuXHRcdFx0ZW5jb2RpbmcgPSBtYXAuZW5jb2Rpbmc7XG5cblx0XHR9IGVsc2UgaWYgKCBtYXAuaXNXZWJHTFJlbmRlclRhcmdldCApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCBcIlRIUkVFLldlYkdMUHJvZ3JhbXMuZ2V0VGV4dHVyZUVuY29kaW5nRnJvbU1hcDogZG9uJ3QgdXNlIHJlbmRlciB0YXJnZXRzIGFzIHRleHR1cmVzLiBVc2UgdGhlaXIgLnRleHR1cmUgcHJvcGVydHkgaW5zdGVhZC5cIiApO1xuXHRcdFx0ZW5jb2RpbmcgPSBtYXAudGV4dHVyZS5lbmNvZGluZztcblxuXHRcdH1cblxuXHRcdC8vIGFkZCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBmb3IgV2ViR0xSZW5kZXJlci5nYW1tYUlucHV0L2dhbW1hT3V0cHV0IHBhcmFtZXRlciwgc2hvdWxkIHByb2JhYmx5IGJlIHJlbW92ZWQgYXQgc29tZSBwb2ludC5cblx0XHRpZiAoIGVuY29kaW5nID09PSBMaW5lYXJFbmNvZGluZyAmJiBnYW1tYU92ZXJyaWRlTGluZWFyICkge1xuXG5cdFx0XHRlbmNvZGluZyA9IEdhbW1hRW5jb2Rpbmc7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gZW5jb2Rpbmc7XG5cblx0fVxuXG5cdHRoaXMuZ2V0UGFyYW1ldGVycyA9IGZ1bmN0aW9uICggbWF0ZXJpYWwsIGxpZ2h0cywgZm9nLCBuQ2xpcFBsYW5lcywgbkNsaXBJbnRlcnNlY3Rpb24sIG9iamVjdCApIHtcblxuXHRcdHZhciBzaGFkZXJJRCA9IHNoYWRlcklEc1sgbWF0ZXJpYWwudHlwZSBdO1xuXG5cdFx0Ly8gaGV1cmlzdGljcyB0byBjcmVhdGUgc2hhZGVyIHBhcmFtZXRlcnMgYWNjb3JkaW5nIHRvIGxpZ2h0cyBpbiB0aGUgc2NlbmVcblx0XHQvLyAobm90IHRvIGJsb3cgb3ZlciBtYXhMaWdodHMgYnVkZ2V0KVxuXG5cdFx0dmFyIG1heEJvbmVzID0gb2JqZWN0LmlzU2tpbm5lZE1lc2ggPyBhbGxvY2F0ZUJvbmVzKCBvYmplY3QgKSA6IDA7XG5cdFx0dmFyIHByZWNpc2lvbiA9IHJlbmRlcmVyLmdldFByZWNpc2lvbigpO1xuXG5cdFx0aWYgKCBtYXRlcmlhbC5wcmVjaXNpb24gIT09IG51bGwgKSB7XG5cblx0XHRcdHByZWNpc2lvbiA9IGNhcGFiaWxpdGllcy5nZXRNYXhQcmVjaXNpb24oIG1hdGVyaWFsLnByZWNpc2lvbiApO1xuXG5cdFx0XHRpZiAoIHByZWNpc2lvbiAhPT0gbWF0ZXJpYWwucHJlY2lzaW9uICkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUHJvZ3JhbS5nZXRQYXJhbWV0ZXJzOicsIG1hdGVyaWFsLnByZWNpc2lvbiwgJ25vdCBzdXBwb3J0ZWQsIHVzaW5nJywgcHJlY2lzaW9uLCAnaW5zdGVhZC4nICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHZhciBjdXJyZW50UmVuZGVyVGFyZ2V0ID0gcmVuZGVyZXIuZ2V0UmVuZGVyVGFyZ2V0KCk7XG5cblx0XHR2YXIgcGFyYW1ldGVycyA9IHtcblxuXHRcdFx0c2hhZGVySUQ6IHNoYWRlcklELFxuXG5cdFx0XHRwcmVjaXNpb246IHByZWNpc2lvbixcblx0XHRcdHN1cHBvcnRzVmVydGV4VGV4dHVyZXM6IGNhcGFiaWxpdGllcy52ZXJ0ZXhUZXh0dXJlcyxcblx0XHRcdG91dHB1dEVuY29kaW5nOiBnZXRUZXh0dXJlRW5jb2RpbmdGcm9tTWFwKCAoICEgY3VycmVudFJlbmRlclRhcmdldCApID8gbnVsbCA6IGN1cnJlbnRSZW5kZXJUYXJnZXQudGV4dHVyZSwgcmVuZGVyZXIuZ2FtbWFPdXRwdXQgKSxcblx0XHRcdG1hcDogISEgbWF0ZXJpYWwubWFwLFxuXHRcdFx0bWFwRW5jb2Rpbmc6IGdldFRleHR1cmVFbmNvZGluZ0Zyb21NYXAoIG1hdGVyaWFsLm1hcCwgcmVuZGVyZXIuZ2FtbWFJbnB1dCApLFxuXHRcdFx0ZW52TWFwOiAhISBtYXRlcmlhbC5lbnZNYXAsXG5cdFx0XHRlbnZNYXBNb2RlOiBtYXRlcmlhbC5lbnZNYXAgJiYgbWF0ZXJpYWwuZW52TWFwLm1hcHBpbmcsXG5cdFx0XHRlbnZNYXBFbmNvZGluZzogZ2V0VGV4dHVyZUVuY29kaW5nRnJvbU1hcCggbWF0ZXJpYWwuZW52TWFwLCByZW5kZXJlci5nYW1tYUlucHV0ICksXG5cdFx0XHRlbnZNYXBDdWJlVVY6ICggISEgbWF0ZXJpYWwuZW52TWFwICkgJiYgKCAoIG1hdGVyaWFsLmVudk1hcC5tYXBwaW5nID09PSBDdWJlVVZSZWZsZWN0aW9uTWFwcGluZyApIHx8ICggbWF0ZXJpYWwuZW52TWFwLm1hcHBpbmcgPT09IEN1YmVVVlJlZnJhY3Rpb25NYXBwaW5nICkgKSxcblx0XHRcdGxpZ2h0TWFwOiAhISBtYXRlcmlhbC5saWdodE1hcCxcblx0XHRcdGFvTWFwOiAhISBtYXRlcmlhbC5hb01hcCxcblx0XHRcdGVtaXNzaXZlTWFwOiAhISBtYXRlcmlhbC5lbWlzc2l2ZU1hcCxcblx0XHRcdGVtaXNzaXZlTWFwRW5jb2Rpbmc6IGdldFRleHR1cmVFbmNvZGluZ0Zyb21NYXAoIG1hdGVyaWFsLmVtaXNzaXZlTWFwLCByZW5kZXJlci5nYW1tYUlucHV0ICksXG5cdFx0XHRidW1wTWFwOiAhISBtYXRlcmlhbC5idW1wTWFwLFxuXHRcdFx0bm9ybWFsTWFwOiAhISBtYXRlcmlhbC5ub3JtYWxNYXAsXG5cdFx0XHRkaXNwbGFjZW1lbnRNYXA6ICEhIG1hdGVyaWFsLmRpc3BsYWNlbWVudE1hcCxcblx0XHRcdHJvdWdobmVzc01hcDogISEgbWF0ZXJpYWwucm91Z2huZXNzTWFwLFxuXHRcdFx0bWV0YWxuZXNzTWFwOiAhISBtYXRlcmlhbC5tZXRhbG5lc3NNYXAsXG5cdFx0XHRzcGVjdWxhck1hcDogISEgbWF0ZXJpYWwuc3BlY3VsYXJNYXAsXG5cdFx0XHRhbHBoYU1hcDogISEgbWF0ZXJpYWwuYWxwaGFNYXAsXG5cblx0XHRcdGdyYWRpZW50TWFwOiAhISBtYXRlcmlhbC5ncmFkaWVudE1hcCxcblxuXHRcdFx0Y29tYmluZTogbWF0ZXJpYWwuY29tYmluZSxcblxuXHRcdFx0dmVydGV4Q29sb3JzOiBtYXRlcmlhbC52ZXJ0ZXhDb2xvcnMsXG5cblx0XHRcdGZvZzogISEgZm9nLFxuXHRcdFx0dXNlRm9nOiBtYXRlcmlhbC5mb2csXG5cdFx0XHRmb2dFeHA6ICggZm9nICYmIGZvZy5pc0ZvZ0V4cDIgKSxcblxuXHRcdFx0ZmxhdFNoYWRpbmc6IG1hdGVyaWFsLnNoYWRpbmcgPT09IEZsYXRTaGFkaW5nLFxuXG5cdFx0XHRzaXplQXR0ZW51YXRpb246IG1hdGVyaWFsLnNpemVBdHRlbnVhdGlvbixcblx0XHRcdGxvZ2FyaXRobWljRGVwdGhCdWZmZXI6IGNhcGFiaWxpdGllcy5sb2dhcml0aG1pY0RlcHRoQnVmZmVyLFxuXG5cdFx0XHRza2lubmluZzogbWF0ZXJpYWwuc2tpbm5pbmcgJiYgbWF4Qm9uZXMgPiAwLFxuXHRcdFx0bWF4Qm9uZXM6IG1heEJvbmVzLFxuXHRcdFx0dXNlVmVydGV4VGV4dHVyZTogY2FwYWJpbGl0aWVzLmZsb2F0VmVydGV4VGV4dHVyZXMsXG5cblx0XHRcdG1vcnBoVGFyZ2V0czogbWF0ZXJpYWwubW9ycGhUYXJnZXRzLFxuXHRcdFx0bW9ycGhOb3JtYWxzOiBtYXRlcmlhbC5tb3JwaE5vcm1hbHMsXG5cdFx0XHRtYXhNb3JwaFRhcmdldHM6IHJlbmRlcmVyLm1heE1vcnBoVGFyZ2V0cyxcblx0XHRcdG1heE1vcnBoTm9ybWFsczogcmVuZGVyZXIubWF4TW9ycGhOb3JtYWxzLFxuXG5cdFx0XHRudW1EaXJMaWdodHM6IGxpZ2h0cy5kaXJlY3Rpb25hbC5sZW5ndGgsXG5cdFx0XHRudW1Qb2ludExpZ2h0czogbGlnaHRzLnBvaW50Lmxlbmd0aCxcblx0XHRcdG51bVNwb3RMaWdodHM6IGxpZ2h0cy5zcG90Lmxlbmd0aCxcblx0XHRcdG51bVJlY3RBcmVhTGlnaHRzOiBsaWdodHMucmVjdEFyZWEubGVuZ3RoLFxuXHRcdFx0bnVtSGVtaUxpZ2h0czogbGlnaHRzLmhlbWkubGVuZ3RoLFxuXG5cdFx0XHRudW1DbGlwcGluZ1BsYW5lczogbkNsaXBQbGFuZXMsXG5cdFx0XHRudW1DbGlwSW50ZXJzZWN0aW9uOiBuQ2xpcEludGVyc2VjdGlvbixcblxuXHRcdFx0ZGl0aGVyaW5nOiBtYXRlcmlhbC5kaXRoZXJpbmcsXG5cblx0XHRcdHNoYWRvd01hcEVuYWJsZWQ6IHJlbmRlcmVyLnNoYWRvd01hcC5lbmFibGVkICYmIG9iamVjdC5yZWNlaXZlU2hhZG93ICYmIGxpZ2h0cy5zaGFkb3dzLmxlbmd0aCA+IDAsXG5cdFx0XHRzaGFkb3dNYXBUeXBlOiByZW5kZXJlci5zaGFkb3dNYXAudHlwZSxcblxuXHRcdFx0dG9uZU1hcHBpbmc6IHJlbmRlcmVyLnRvbmVNYXBwaW5nLFxuXHRcdFx0cGh5c2ljYWxseUNvcnJlY3RMaWdodHM6IHJlbmRlcmVyLnBoeXNpY2FsbHlDb3JyZWN0TGlnaHRzLFxuXG5cdFx0XHRwcmVtdWx0aXBsaWVkQWxwaGE6IG1hdGVyaWFsLnByZW11bHRpcGxpZWRBbHBoYSxcblxuXHRcdFx0YWxwaGFUZXN0OiBtYXRlcmlhbC5hbHBoYVRlc3QsXG5cdFx0XHRkb3VibGVTaWRlZDogbWF0ZXJpYWwuc2lkZSA9PT0gRG91YmxlU2lkZSxcblx0XHRcdGZsaXBTaWRlZDogbWF0ZXJpYWwuc2lkZSA9PT0gQmFja1NpZGUsXG5cblx0XHRcdGRlcHRoUGFja2luZzogKCBtYXRlcmlhbC5kZXB0aFBhY2tpbmcgIT09IHVuZGVmaW5lZCApID8gbWF0ZXJpYWwuZGVwdGhQYWNraW5nIDogZmFsc2VcblxuXHRcdH07XG5cblx0XHRyZXR1cm4gcGFyYW1ldGVycztcblxuXHR9O1xuXG5cdHRoaXMuZ2V0UHJvZ3JhbUNvZGUgPSBmdW5jdGlvbiAoIG1hdGVyaWFsLCBwYXJhbWV0ZXJzICkge1xuXG5cdFx0dmFyIGFycmF5ID0gW107XG5cblx0XHRpZiAoIHBhcmFtZXRlcnMuc2hhZGVySUQgKSB7XG5cblx0XHRcdGFycmF5LnB1c2goIHBhcmFtZXRlcnMuc2hhZGVySUQgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGFycmF5LnB1c2goIG1hdGVyaWFsLmZyYWdtZW50U2hhZGVyICk7XG5cdFx0XHRhcnJheS5wdXNoKCBtYXRlcmlhbC52ZXJ0ZXhTaGFkZXIgKTtcblxuXHRcdH1cblxuXHRcdGlmICggbWF0ZXJpYWwuZGVmaW5lcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgbmFtZSBpbiBtYXRlcmlhbC5kZWZpbmVzICkge1xuXG5cdFx0XHRcdGFycmF5LnB1c2goIG5hbWUgKTtcblx0XHRcdFx0YXJyYXkucHVzaCggbWF0ZXJpYWwuZGVmaW5lc1sgbmFtZSBdICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHBhcmFtZXRlck5hbWVzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0YXJyYXkucHVzaCggcGFyYW1ldGVyc1sgcGFyYW1ldGVyTmFtZXNbIGkgXSBdICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyYXkuam9pbigpO1xuXG5cdH07XG5cblx0dGhpcy5hY3F1aXJlUHJvZ3JhbSA9IGZ1bmN0aW9uICggbWF0ZXJpYWwsIHBhcmFtZXRlcnMsIGNvZGUgKSB7XG5cblx0XHR2YXIgcHJvZ3JhbTtcblxuXHRcdC8vIENoZWNrIGlmIGNvZGUgaGFzIGJlZW4gYWxyZWFkeSBjb21waWxlZFxuXHRcdGZvciAoIHZhciBwID0gMCwgcGwgPSBwcm9ncmFtcy5sZW5ndGg7IHAgPCBwbDsgcCArKyApIHtcblxuXHRcdFx0dmFyIHByb2dyYW1JbmZvID0gcHJvZ3JhbXNbIHAgXTtcblxuXHRcdFx0aWYgKCBwcm9ncmFtSW5mby5jb2RlID09PSBjb2RlICkge1xuXG5cdFx0XHRcdHByb2dyYW0gPSBwcm9ncmFtSW5mbztcblx0XHRcdFx0KysgcHJvZ3JhbS51c2VkVGltZXM7XG5cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggcHJvZ3JhbSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRwcm9ncmFtID0gbmV3IFdlYkdMUHJvZ3JhbSggcmVuZGVyZXIsIGNvZGUsIG1hdGVyaWFsLCBwYXJhbWV0ZXJzICk7XG5cdFx0XHRwcm9ncmFtcy5wdXNoKCBwcm9ncmFtICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcHJvZ3JhbTtcblxuXHR9O1xuXG5cdHRoaXMucmVsZWFzZVByb2dyYW0gPSBmdW5jdGlvbiAoIHByb2dyYW0gKSB7XG5cblx0XHRpZiAoIC0tIHByb2dyYW0udXNlZFRpbWVzID09PSAwICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgZnJvbSB1bm9yZGVyZWQgc2V0XG5cdFx0XHR2YXIgaSA9IHByb2dyYW1zLmluZGV4T2YoIHByb2dyYW0gKTtcblx0XHRcdHByb2dyYW1zWyBpIF0gPSBwcm9ncmFtc1sgcHJvZ3JhbXMubGVuZ3RoIC0gMSBdO1xuXHRcdFx0cHJvZ3JhbXMucG9wKCk7XG5cblx0XHRcdC8vIEZyZWUgV2ViR0wgcmVzb3VyY2VzXG5cdFx0XHRwcm9ncmFtLmRlc3Ryb3koKTtcblxuXHRcdH1cblxuXHR9O1xuXG5cdC8vIEV4cG9zZWQgZm9yIHJlc291cmNlIG1vbml0b3JpbmcgJiBlcnJvciBmZWVkYmFjayB2aWEgcmVuZGVyZXIuaW5mbzpcblx0dGhpcy5wcm9ncmFtcyA9IHByb2dyYW1zO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTFRleHR1cmVzKCBfZ2wsIGV4dGVuc2lvbnMsIHN0YXRlLCBwcm9wZXJ0aWVzLCBjYXBhYmlsaXRpZXMsIHBhcmFtVGhyZWVUb0dMLCBpbmZvTWVtb3J5ICkge1xuXG5cdHZhciBfaXNXZWJHTDIgPSAoIHR5cGVvZiBXZWJHTDJSZW5kZXJpbmdDb250ZXh0ICE9PSAndW5kZWZpbmVkJyAmJiBfZ2wgaW5zdGFuY2VvZiBXZWJHTDJSZW5kZXJpbmdDb250ZXh0ICk7XG5cblx0Ly9cblxuXHRmdW5jdGlvbiBjbGFtcFRvTWF4U2l6ZSggaW1hZ2UsIG1heFNpemUgKSB7XG5cblx0XHRpZiAoIGltYWdlLndpZHRoID4gbWF4U2l6ZSB8fCBpbWFnZS5oZWlnaHQgPiBtYXhTaXplICkge1xuXG5cdFx0XHQvLyBXYXJuaW5nOiBTY2FsaW5nIHRocm91Z2ggdGhlIGNhbnZhcyB3aWxsIG9ubHkgd29yayB3aXRoIGltYWdlcyB0aGF0IHVzZVxuXHRcdFx0Ly8gcHJlbXVsdGlwbGllZCBhbHBoYS5cblxuXHRcdFx0dmFyIHNjYWxlID0gbWF4U2l6ZSAvIE1hdGgubWF4KCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0ICk7XG5cblx0XHRcdHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJywgJ2NhbnZhcycgKTtcblx0XHRcdGNhbnZhcy53aWR0aCA9IE1hdGguZmxvb3IoIGltYWdlLndpZHRoICogc2NhbGUgKTtcblx0XHRcdGNhbnZhcy5oZWlnaHQgPSBNYXRoLmZsb29yKCBpbWFnZS5oZWlnaHQgKiBzY2FsZSApO1xuXG5cdFx0XHR2YXIgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCAnMmQnICk7XG5cdFx0XHRjb250ZXh0LmRyYXdJbWFnZSggaW1hZ2UsIDAsIDAsIGltYWdlLndpZHRoLCBpbWFnZS5oZWlnaHQsIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCApO1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBpbWFnZSBpcyB0b28gYmlnICgnICsgaW1hZ2Uud2lkdGggKyAneCcgKyBpbWFnZS5oZWlnaHQgKyAnKS4gUmVzaXplZCB0byAnICsgY2FudmFzLndpZHRoICsgJ3gnICsgY2FudmFzLmhlaWdodCwgaW1hZ2UgKTtcblxuXHRcdFx0cmV0dXJuIGNhbnZhcztcblxuXHRcdH1cblxuXHRcdHJldHVybiBpbWFnZTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gaXNQb3dlck9mVHdvKCBpbWFnZSApIHtcblxuXHRcdHJldHVybiBfTWF0aC5pc1Bvd2VyT2ZUd28oIGltYWdlLndpZHRoICkgJiYgX01hdGguaXNQb3dlck9mVHdvKCBpbWFnZS5oZWlnaHQgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gbWFrZVBvd2VyT2ZUd28oIGltYWdlICkge1xuXG5cdFx0aWYgKCBpbWFnZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQgfHwgaW1hZ2UgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCApIHtcblxuXHRcdFx0dmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyggJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnLCAnY2FudmFzJyApO1xuXHRcdFx0Y2FudmFzLndpZHRoID0gX01hdGgubmVhcmVzdFBvd2VyT2ZUd28oIGltYWdlLndpZHRoICk7XG5cdFx0XHRjYW52YXMuaGVpZ2h0ID0gX01hdGgubmVhcmVzdFBvd2VyT2ZUd28oIGltYWdlLmhlaWdodCApO1xuXG5cdFx0XHR2YXIgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCAnMmQnICk7XG5cdFx0XHRjb250ZXh0LmRyYXdJbWFnZSggaW1hZ2UsIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCApO1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBpbWFnZSBpcyBub3QgcG93ZXIgb2YgdHdvICgnICsgaW1hZ2Uud2lkdGggKyAneCcgKyBpbWFnZS5oZWlnaHQgKyAnKS4gUmVzaXplZCB0byAnICsgY2FudmFzLndpZHRoICsgJ3gnICsgY2FudmFzLmhlaWdodCwgaW1hZ2UgKTtcblxuXHRcdFx0cmV0dXJuIGNhbnZhcztcblxuXHRcdH1cblxuXHRcdHJldHVybiBpbWFnZTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gdGV4dHVyZU5lZWRzUG93ZXJPZlR3byggdGV4dHVyZSApIHtcblxuXHRcdHJldHVybiAoIHRleHR1cmUud3JhcFMgIT09IENsYW1wVG9FZGdlV3JhcHBpbmcgfHwgdGV4dHVyZS53cmFwVCAhPT0gQ2xhbXBUb0VkZ2VXcmFwcGluZyApIHx8XG5cdFx0XHQoIHRleHR1cmUubWluRmlsdGVyICE9PSBOZWFyZXN0RmlsdGVyICYmIHRleHR1cmUubWluRmlsdGVyICE9PSBMaW5lYXJGaWx0ZXIgKTtcblxuXHR9XG5cblx0Ly8gRmFsbGJhY2sgZmlsdGVycyBmb3Igbm9uLXBvd2VyLW9mLTIgdGV4dHVyZXNcblxuXHRmdW5jdGlvbiBmaWx0ZXJGYWxsYmFjayggZiApIHtcblxuXHRcdGlmICggZiA9PT0gTmVhcmVzdEZpbHRlciB8fCBmID09PSBOZWFyZXN0TWlwTWFwTmVhcmVzdEZpbHRlciB8fCBmID09PSBOZWFyZXN0TWlwTWFwTGluZWFyRmlsdGVyICkge1xuXG5cdFx0XHRyZXR1cm4gX2dsLk5FQVJFU1Q7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gX2dsLkxJTkVBUjtcblxuXHR9XG5cblx0Ly9cblxuXHRmdW5jdGlvbiBvblRleHR1cmVEaXNwb3NlKCBldmVudCApIHtcblxuXHRcdHZhciB0ZXh0dXJlID0gZXZlbnQudGFyZ2V0O1xuXG5cdFx0dGV4dHVyZS5yZW1vdmVFdmVudExpc3RlbmVyKCAnZGlzcG9zZScsIG9uVGV4dHVyZURpc3Bvc2UgKTtcblxuXHRcdGRlYWxsb2NhdGVUZXh0dXJlKCB0ZXh0dXJlICk7XG5cblx0XHRpbmZvTWVtb3J5LnRleHR1cmVzIC0tO1xuXG5cblx0fVxuXG5cdGZ1bmN0aW9uIG9uUmVuZGVyVGFyZ2V0RGlzcG9zZSggZXZlbnQgKSB7XG5cblx0XHR2YXIgcmVuZGVyVGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuXG5cdFx0cmVuZGVyVGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoICdkaXNwb3NlJywgb25SZW5kZXJUYXJnZXREaXNwb3NlICk7XG5cblx0XHRkZWFsbG9jYXRlUmVuZGVyVGFyZ2V0KCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdGluZm9NZW1vcnkudGV4dHVyZXMgLS07XG5cblx0fVxuXG5cdC8vXG5cblx0ZnVuY3Rpb24gZGVhbGxvY2F0ZVRleHR1cmUoIHRleHR1cmUgKSB7XG5cblx0XHR2YXIgdGV4dHVyZVByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggdGV4dHVyZSApO1xuXG5cdFx0aWYgKCB0ZXh0dXJlLmltYWdlICYmIHRleHR1cmVQcm9wZXJ0aWVzLl9faW1hZ2VfX3dlYmdsVGV4dHVyZUN1YmUgKSB7XG5cblx0XHRcdC8vIGN1YmUgdGV4dHVyZVxuXG5cdFx0XHRfZ2wuZGVsZXRlVGV4dHVyZSggdGV4dHVyZVByb3BlcnRpZXMuX19pbWFnZV9fd2ViZ2xUZXh0dXJlQ3ViZSApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gMkQgdGV4dHVyZVxuXG5cdFx0XHRpZiAoIHRleHR1cmVQcm9wZXJ0aWVzLl9fd2ViZ2xJbml0ID09PSB1bmRlZmluZWQgKSByZXR1cm47XG5cblx0XHRcdF9nbC5kZWxldGVUZXh0dXJlKCB0ZXh0dXJlUHJvcGVydGllcy5fX3dlYmdsVGV4dHVyZSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gcmVtb3ZlIGFsbCB3ZWJnbCBwcm9wZXJ0aWVzXG5cdFx0cHJvcGVydGllcy5yZW1vdmUoIHRleHR1cmUgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gZGVhbGxvY2F0ZVJlbmRlclRhcmdldCggcmVuZGVyVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlbmRlclRhcmdldFByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0ICk7XG5cdFx0dmFyIHRleHR1cmVQcm9wZXJ0aWVzID0gcHJvcGVydGllcy5nZXQoIHJlbmRlclRhcmdldC50ZXh0dXJlICk7XG5cblx0XHRpZiAoICEgcmVuZGVyVGFyZ2V0ICkgcmV0dXJuO1xuXG5cdFx0aWYgKCB0ZXh0dXJlUHJvcGVydGllcy5fX3dlYmdsVGV4dHVyZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRfZ2wuZGVsZXRlVGV4dHVyZSggdGV4dHVyZVByb3BlcnRpZXMuX193ZWJnbFRleHR1cmUgKTtcblxuXHRcdH1cblxuXHRcdGlmICggcmVuZGVyVGFyZ2V0LmRlcHRoVGV4dHVyZSApIHtcblxuXHRcdFx0cmVuZGVyVGFyZ2V0LmRlcHRoVGV4dHVyZS5kaXNwb3NlKCk7XG5cblx0XHR9XG5cblx0XHRpZiAoIHJlbmRlclRhcmdldC5pc1dlYkdMUmVuZGVyVGFyZ2V0Q3ViZSApIHtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0XHRfZ2wuZGVsZXRlRnJhbWVidWZmZXIoIHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbEZyYW1lYnVmZmVyWyBpIF0gKTtcblx0XHRcdFx0aWYgKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xEZXB0aGJ1ZmZlciApIF9nbC5kZWxldGVSZW5kZXJidWZmZXIoIHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbERlcHRoYnVmZmVyWyBpIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0X2dsLmRlbGV0ZUZyYW1lYnVmZmVyKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xGcmFtZWJ1ZmZlciApO1xuXHRcdFx0aWYgKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xEZXB0aGJ1ZmZlciApIF9nbC5kZWxldGVSZW5kZXJidWZmZXIoIHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbERlcHRoYnVmZmVyICk7XG5cblx0XHR9XG5cblx0XHRwcm9wZXJ0aWVzLnJlbW92ZSggcmVuZGVyVGFyZ2V0LnRleHR1cmUgKTtcblx0XHRwcm9wZXJ0aWVzLnJlbW92ZSggcmVuZGVyVGFyZ2V0ICk7XG5cblx0fVxuXG5cdC8vXG5cblxuXG5cdGZ1bmN0aW9uIHNldFRleHR1cmUyRCggdGV4dHVyZSwgc2xvdCApIHtcblxuXHRcdHZhciB0ZXh0dXJlUHJvcGVydGllcyA9IHByb3BlcnRpZXMuZ2V0KCB0ZXh0dXJlICk7XG5cblx0XHRpZiAoIHRleHR1cmUudmVyc2lvbiA+IDAgJiYgdGV4dHVyZVByb3BlcnRpZXMuX192ZXJzaW9uICE9PSB0ZXh0dXJlLnZlcnNpb24gKSB7XG5cblx0XHRcdHZhciBpbWFnZSA9IHRleHR1cmUuaW1hZ2U7XG5cblx0XHRcdGlmICggaW1hZ2UgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBUZXh0dXJlIG1hcmtlZCBmb3IgdXBkYXRlIGJ1dCBpbWFnZSBpcyB1bmRlZmluZWQnLCB0ZXh0dXJlICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGltYWdlLmNvbXBsZXRlID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBUZXh0dXJlIG1hcmtlZCBmb3IgdXBkYXRlIGJ1dCBpbWFnZSBpcyBpbmNvbXBsZXRlJywgdGV4dHVyZSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHVwbG9hZFRleHR1cmUoIHRleHR1cmVQcm9wZXJ0aWVzLCB0ZXh0dXJlLCBzbG90ICk7XG5cdFx0XHRcdHJldHVybjtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggX2dsLlRFWFRVUkUwICsgc2xvdCApO1xuXHRcdHN0YXRlLmJpbmRUZXh0dXJlKCBfZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZVByb3BlcnRpZXMuX193ZWJnbFRleHR1cmUgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0VGV4dHVyZUN1YmUoIHRleHR1cmUsIHNsb3QgKSB7XG5cblx0XHR2YXIgdGV4dHVyZVByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggdGV4dHVyZSApO1xuXG5cdFx0aWYgKCB0ZXh0dXJlLmltYWdlLmxlbmd0aCA9PT0gNiApIHtcblxuXHRcdFx0aWYgKCB0ZXh0dXJlLnZlcnNpb24gPiAwICYmIHRleHR1cmVQcm9wZXJ0aWVzLl9fdmVyc2lvbiAhPT0gdGV4dHVyZS52ZXJzaW9uICkge1xuXG5cdFx0XHRcdGlmICggISB0ZXh0dXJlUHJvcGVydGllcy5fX2ltYWdlX193ZWJnbFRleHR1cmVDdWJlICkge1xuXG5cdFx0XHRcdFx0dGV4dHVyZS5hZGRFdmVudExpc3RlbmVyKCAnZGlzcG9zZScsIG9uVGV4dHVyZURpc3Bvc2UgKTtcblxuXHRcdFx0XHRcdHRleHR1cmVQcm9wZXJ0aWVzLl9faW1hZ2VfX3dlYmdsVGV4dHVyZUN1YmUgPSBfZ2wuY3JlYXRlVGV4dHVyZSgpO1xuXG5cdFx0XHRcdFx0aW5mb01lbW9yeS50ZXh0dXJlcyArKztcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggX2dsLlRFWFRVUkUwICsgc2xvdCApO1xuXHRcdFx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggX2dsLlRFWFRVUkVfQ1VCRV9NQVAsIHRleHR1cmVQcm9wZXJ0aWVzLl9faW1hZ2VfX3dlYmdsVGV4dHVyZUN1YmUgKTtcblxuXHRcdFx0XHRfZ2wucGl4ZWxTdG9yZWkoIF9nbC5VTlBBQ0tfRkxJUF9ZX1dFQkdMLCB0ZXh0dXJlLmZsaXBZICk7XG5cblx0XHRcdFx0dmFyIGlzQ29tcHJlc3NlZCA9ICggdGV4dHVyZSAmJiB0ZXh0dXJlLmlzQ29tcHJlc3NlZFRleHR1cmUgKTtcblx0XHRcdFx0dmFyIGlzRGF0YVRleHR1cmUgPSAoIHRleHR1cmUuaW1hZ2VbIDAgXSAmJiB0ZXh0dXJlLmltYWdlWyAwIF0uaXNEYXRhVGV4dHVyZSApO1xuXG5cdFx0XHRcdHZhciBjdWJlSW1hZ2UgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCA2OyBpICsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCAhIGlzQ29tcHJlc3NlZCAmJiAhIGlzRGF0YVRleHR1cmUgKSB7XG5cblx0XHRcdFx0XHRcdGN1YmVJbWFnZVsgaSBdID0gY2xhbXBUb01heFNpemUoIHRleHR1cmUuaW1hZ2VbIGkgXSwgY2FwYWJpbGl0aWVzLm1heEN1YmVtYXBTaXplICk7XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRjdWJlSW1hZ2VbIGkgXSA9IGlzRGF0YVRleHR1cmUgPyB0ZXh0dXJlLmltYWdlWyBpIF0uaW1hZ2UgOiB0ZXh0dXJlLmltYWdlWyBpIF07XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBpbWFnZSA9IGN1YmVJbWFnZVsgMCBdLFxuXHRcdFx0XHRpc1Bvd2VyT2ZUd29JbWFnZSA9IGlzUG93ZXJPZlR3byggaW1hZ2UgKSxcblx0XHRcdFx0Z2xGb3JtYXQgPSBwYXJhbVRocmVlVG9HTCggdGV4dHVyZS5mb3JtYXQgKSxcblx0XHRcdFx0Z2xUeXBlID0gcGFyYW1UaHJlZVRvR0woIHRleHR1cmUudHlwZSApO1xuXG5cdFx0XHRcdHNldFRleHR1cmVQYXJhbWV0ZXJzKCBfZ2wuVEVYVFVSRV9DVUJFX01BUCwgdGV4dHVyZSwgaXNQb3dlck9mVHdvSW1hZ2UgKTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCA2OyBpICsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCAhIGlzQ29tcHJlc3NlZCApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBpc0RhdGFUZXh0dXJlICkge1xuXG5cdFx0XHRcdFx0XHRcdHN0YXRlLnRleEltYWdlMkQoIF9nbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyBpLCAwLCBnbEZvcm1hdCwgY3ViZUltYWdlWyBpIF0ud2lkdGgsIGN1YmVJbWFnZVsgaSBdLmhlaWdodCwgMCwgZ2xGb3JtYXQsIGdsVHlwZSwgY3ViZUltYWdlWyBpIF0uZGF0YSApO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdHN0YXRlLnRleEltYWdlMkQoIF9nbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyBpLCAwLCBnbEZvcm1hdCwgZ2xGb3JtYXQsIGdsVHlwZSwgY3ViZUltYWdlWyBpIF0gKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0dmFyIG1pcG1hcCwgbWlwbWFwcyA9IGN1YmVJbWFnZVsgaSBdLm1pcG1hcHM7XG5cblx0XHRcdFx0XHRcdGZvciAoIHZhciBqID0gMCwgamwgPSBtaXBtYXBzLmxlbmd0aDsgaiA8IGpsOyBqICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdG1pcG1hcCA9IG1pcG1hcHNbIGogXTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHRleHR1cmUuZm9ybWF0ICE9PSBSR0JBRm9ybWF0ICYmIHRleHR1cmUuZm9ybWF0ICE9PSBSR0JGb3JtYXQgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRpZiAoIHN0YXRlLmdldENvbXByZXNzZWRUZXh0dXJlRm9ybWF0cygpLmluZGV4T2YoIGdsRm9ybWF0ICkgPiAtIDEgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdHN0YXRlLmNvbXByZXNzZWRUZXhJbWFnZTJEKCBfZ2wuVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YICsgaSwgaiwgZ2xGb3JtYXQsIG1pcG1hcC53aWR0aCwgbWlwbWFwLmhlaWdodCwgMCwgbWlwbWFwLmRhdGEgKTtcblxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdGNvbnNvbGUud2FybiggXCJUSFJFRS5XZWJHTFJlbmRlcmVyOiBBdHRlbXB0IHRvIGxvYWQgdW5zdXBwb3J0ZWQgY29tcHJlc3NlZCB0ZXh0dXJlIGZvcm1hdCBpbiAuc2V0VGV4dHVyZUN1YmUoKVwiICk7XG5cblx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdHN0YXRlLnRleEltYWdlMkQoIF9nbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyBpLCBqLCBnbEZvcm1hdCwgbWlwbWFwLndpZHRoLCBtaXBtYXAuaGVpZ2h0LCAwLCBnbEZvcm1hdCwgZ2xUeXBlLCBtaXBtYXAuZGF0YSApO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzICYmIGlzUG93ZXJPZlR3b0ltYWdlICkge1xuXG5cdFx0XHRcdFx0X2dsLmdlbmVyYXRlTWlwbWFwKCBfZ2wuVEVYVFVSRV9DVUJFX01BUCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0ZXh0dXJlUHJvcGVydGllcy5fX3ZlcnNpb24gPSB0ZXh0dXJlLnZlcnNpb247XG5cblx0XHRcdFx0aWYgKCB0ZXh0dXJlLm9uVXBkYXRlICkgdGV4dHVyZS5vblVwZGF0ZSggdGV4dHVyZSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHN0YXRlLmFjdGl2ZVRleHR1cmUoIF9nbC5URVhUVVJFMCArIHNsb3QgKTtcblx0XHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIF9nbC5URVhUVVJFX0NVQkVfTUFQLCB0ZXh0dXJlUHJvcGVydGllcy5fX2ltYWdlX193ZWJnbFRleHR1cmVDdWJlICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0VGV4dHVyZUN1YmVEeW5hbWljKCB0ZXh0dXJlLCBzbG90ICkge1xuXG5cdFx0c3RhdGUuYWN0aXZlVGV4dHVyZSggX2dsLlRFWFRVUkUwICsgc2xvdCApO1xuXHRcdHN0YXRlLmJpbmRUZXh0dXJlKCBfZ2wuVEVYVFVSRV9DVUJFX01BUCwgcHJvcGVydGllcy5nZXQoIHRleHR1cmUgKS5fX3dlYmdsVGV4dHVyZSApO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBzZXRUZXh0dXJlUGFyYW1ldGVycyggdGV4dHVyZVR5cGUsIHRleHR1cmUsIGlzUG93ZXJPZlR3b0ltYWdlICkge1xuXG5cdFx0dmFyIGV4dGVuc2lvbjtcblxuXHRcdGlmICggaXNQb3dlck9mVHdvSW1hZ2UgKSB7XG5cblx0XHRcdF9nbC50ZXhQYXJhbWV0ZXJpKCB0ZXh0dXJlVHlwZSwgX2dsLlRFWFRVUkVfV1JBUF9TLCBwYXJhbVRocmVlVG9HTCggdGV4dHVyZS53cmFwUyApICk7XG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX1dSQVBfVCwgcGFyYW1UaHJlZVRvR0woIHRleHR1cmUud3JhcFQgKSApO1xuXG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX01BR19GSUxURVIsIHBhcmFtVGhyZWVUb0dMKCB0ZXh0dXJlLm1hZ0ZpbHRlciApICk7XG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX01JTl9GSUxURVIsIHBhcmFtVGhyZWVUb0dMKCB0ZXh0dXJlLm1pbkZpbHRlciApICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX1dSQVBfUywgX2dsLkNMQU1QX1RPX0VER0UgKTtcblx0XHRcdF9nbC50ZXhQYXJhbWV0ZXJpKCB0ZXh0dXJlVHlwZSwgX2dsLlRFWFRVUkVfV1JBUF9ULCBfZ2wuQ0xBTVBfVE9fRURHRSApO1xuXG5cdFx0XHRpZiAoIHRleHR1cmUud3JhcFMgIT09IENsYW1wVG9FZGdlV3JhcHBpbmcgfHwgdGV4dHVyZS53cmFwVCAhPT0gQ2xhbXBUb0VkZ2VXcmFwcGluZyApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBUZXh0dXJlIGlzIG5vdCBwb3dlciBvZiB0d28uIFRleHR1cmUud3JhcFMgYW5kIFRleHR1cmUud3JhcFQgc2hvdWxkIGJlIHNldCB0byBUSFJFRS5DbGFtcFRvRWRnZVdyYXBwaW5nLicsIHRleHR1cmUgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX01BR19GSUxURVIsIGZpbHRlckZhbGxiYWNrKCB0ZXh0dXJlLm1hZ0ZpbHRlciApICk7XG5cdFx0XHRfZ2wudGV4UGFyYW1ldGVyaSggdGV4dHVyZVR5cGUsIF9nbC5URVhUVVJFX01JTl9GSUxURVIsIGZpbHRlckZhbGxiYWNrKCB0ZXh0dXJlLm1pbkZpbHRlciApICk7XG5cblx0XHRcdGlmICggdGV4dHVyZS5taW5GaWx0ZXIgIT09IE5lYXJlc3RGaWx0ZXIgJiYgdGV4dHVyZS5taW5GaWx0ZXIgIT09IExpbmVhckZpbHRlciApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBUZXh0dXJlIGlzIG5vdCBwb3dlciBvZiB0d28uIFRleHR1cmUubWluRmlsdGVyIHNob3VsZCBiZSBzZXQgdG8gVEhSRUUuTmVhcmVzdEZpbHRlciBvciBUSFJFRS5MaW5lYXJGaWx0ZXIuJywgdGV4dHVyZSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ0VYVF90ZXh0dXJlX2ZpbHRlcl9hbmlzb3Ryb3BpYycgKTtcblxuXHRcdGlmICggZXh0ZW5zaW9uICkge1xuXG5cdFx0XHRpZiAoIHRleHR1cmUudHlwZSA9PT0gRmxvYXRUeXBlICYmIGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3RleHR1cmVfZmxvYXRfbGluZWFyJyApID09PSBudWxsICkgcmV0dXJuO1xuXHRcdFx0aWYgKCB0ZXh0dXJlLnR5cGUgPT09IEhhbGZGbG9hdFR5cGUgJiYgZXh0ZW5zaW9ucy5nZXQoICdPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0X2xpbmVhcicgKSA9PT0gbnVsbCApIHJldHVybjtcblxuXHRcdFx0aWYgKCB0ZXh0dXJlLmFuaXNvdHJvcHkgPiAxIHx8IHByb3BlcnRpZXMuZ2V0KCB0ZXh0dXJlICkuX19jdXJyZW50QW5pc290cm9weSApIHtcblxuXHRcdFx0XHRfZ2wudGV4UGFyYW1ldGVyZiggdGV4dHVyZVR5cGUsIGV4dGVuc2lvbi5URVhUVVJFX01BWF9BTklTT1RST1BZX0VYVCwgTWF0aC5taW4oIHRleHR1cmUuYW5pc290cm9weSwgY2FwYWJpbGl0aWVzLmdldE1heEFuaXNvdHJvcHkoKSApICk7XG5cdFx0XHRcdHByb3BlcnRpZXMuZ2V0KCB0ZXh0dXJlICkuX19jdXJyZW50QW5pc290cm9weSA9IHRleHR1cmUuYW5pc290cm9weTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiB1cGxvYWRUZXh0dXJlKCB0ZXh0dXJlUHJvcGVydGllcywgdGV4dHVyZSwgc2xvdCApIHtcblxuXHRcdGlmICggdGV4dHVyZVByb3BlcnRpZXMuX193ZWJnbEluaXQgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dGV4dHVyZVByb3BlcnRpZXMuX193ZWJnbEluaXQgPSB0cnVlO1xuXG5cdFx0XHR0ZXh0dXJlLmFkZEV2ZW50TGlzdGVuZXIoICdkaXNwb3NlJywgb25UZXh0dXJlRGlzcG9zZSApO1xuXG5cdFx0XHR0ZXh0dXJlUHJvcGVydGllcy5fX3dlYmdsVGV4dHVyZSA9IF9nbC5jcmVhdGVUZXh0dXJlKCk7XG5cblx0XHRcdGluZm9NZW1vcnkudGV4dHVyZXMgKys7XG5cblx0XHR9XG5cblx0XHRzdGF0ZS5hY3RpdmVUZXh0dXJlKCBfZ2wuVEVYVFVSRTAgKyBzbG90ICk7XG5cdFx0c3RhdGUuYmluZFRleHR1cmUoIF9nbC5URVhUVVJFXzJELCB0ZXh0dXJlUHJvcGVydGllcy5fX3dlYmdsVGV4dHVyZSApO1xuXG5cdFx0X2dsLnBpeGVsU3RvcmVpKCBfZ2wuVU5QQUNLX0ZMSVBfWV9XRUJHTCwgdGV4dHVyZS5mbGlwWSApO1xuXHRcdF9nbC5waXhlbFN0b3JlaSggX2dsLlVOUEFDS19QUkVNVUxUSVBMWV9BTFBIQV9XRUJHTCwgdGV4dHVyZS5wcmVtdWx0aXBseUFscGhhICk7XG5cdFx0X2dsLnBpeGVsU3RvcmVpKCBfZ2wuVU5QQUNLX0FMSUdOTUVOVCwgdGV4dHVyZS51bnBhY2tBbGlnbm1lbnQgKTtcblxuXHRcdHZhciBpbWFnZSA9IGNsYW1wVG9NYXhTaXplKCB0ZXh0dXJlLmltYWdlLCBjYXBhYmlsaXRpZXMubWF4VGV4dHVyZVNpemUgKTtcblxuXHRcdGlmICggdGV4dHVyZU5lZWRzUG93ZXJPZlR3byggdGV4dHVyZSApICYmIGlzUG93ZXJPZlR3byggaW1hZ2UgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGltYWdlID0gbWFrZVBvd2VyT2ZUd28oIGltYWdlICk7XG5cblx0XHR9XG5cblx0XHR2YXIgaXNQb3dlck9mVHdvSW1hZ2UgPSBpc1Bvd2VyT2ZUd28oIGltYWdlICksXG5cdFx0Z2xGb3JtYXQgPSBwYXJhbVRocmVlVG9HTCggdGV4dHVyZS5mb3JtYXQgKSxcblx0XHRnbFR5cGUgPSBwYXJhbVRocmVlVG9HTCggdGV4dHVyZS50eXBlICk7XG5cblx0XHRzZXRUZXh0dXJlUGFyYW1ldGVycyggX2dsLlRFWFRVUkVfMkQsIHRleHR1cmUsIGlzUG93ZXJPZlR3b0ltYWdlICk7XG5cblx0XHR2YXIgbWlwbWFwLCBtaXBtYXBzID0gdGV4dHVyZS5taXBtYXBzO1xuXG5cdFx0aWYgKCB0ZXh0dXJlLmlzRGVwdGhUZXh0dXJlICkge1xuXG5cdFx0XHQvLyBwb3B1bGF0ZSBkZXB0aCB0ZXh0dXJlIHdpdGggZHVtbXkgZGF0YVxuXG5cdFx0XHR2YXIgaW50ZXJuYWxGb3JtYXQgPSBfZ2wuREVQVEhfQ09NUE9ORU5UO1xuXG5cdFx0XHRpZiAoIHRleHR1cmUudHlwZSA9PT0gRmxvYXRUeXBlICkge1xuXG5cdFx0XHRcdGlmICggIV9pc1dlYkdMMiApIHRocm93IG5ldyBFcnJvcignRmxvYXQgRGVwdGggVGV4dHVyZSBvbmx5IHN1cHBvcnRlZCBpbiBXZWJHTDIuMCcpO1xuXHRcdFx0XHRpbnRlcm5hbEZvcm1hdCA9IF9nbC5ERVBUSF9DT01QT05FTlQzMkY7XG5cblx0XHRcdH0gZWxzZSBpZiAoIF9pc1dlYkdMMiApIHtcblxuXHRcdFx0XHQvLyBXZWJHTCAyLjAgcmVxdWlyZXMgc2lnbmVkIGludGVybmFsZm9ybWF0IGZvciBnbFRleEltYWdlMkRcblx0XHRcdFx0aW50ZXJuYWxGb3JtYXQgPSBfZ2wuREVQVEhfQ09NUE9ORU5UMTY7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCB0ZXh0dXJlLmZvcm1hdCA9PT0gRGVwdGhGb3JtYXQgJiYgaW50ZXJuYWxGb3JtYXQgPT09IF9nbC5ERVBUSF9DT01QT05FTlQgKSB7XG5cblx0XHRcdFx0Ly8gVGhlIGVycm9yIElOVkFMSURfT1BFUkFUSU9OIGlzIGdlbmVyYXRlZCBieSB0ZXhJbWFnZTJEIGlmIGZvcm1hdCBhbmQgaW50ZXJuYWxmb3JtYXQgYXJlXG5cdFx0XHRcdC8vIERFUFRIX0NPTVBPTkVOVCBhbmQgdHlwZSBpcyBub3QgVU5TSUdORURfU0hPUlQgb3IgVU5TSUdORURfSU5UXG5cdFx0XHRcdC8vIChodHRwczovL3d3dy5raHJvbm9zLm9yZy9yZWdpc3RyeS93ZWJnbC9leHRlbnNpb25zL1dFQkdMX2RlcHRoX3RleHR1cmUvKVxuXHRcdFx0XHRpZiAoIHRleHR1cmUudHlwZSAhPT0gVW5zaWduZWRTaG9ydFR5cGUgJiYgdGV4dHVyZS50eXBlICE9PSBVbnNpZ25lZEludFR5cGUgKSB7XG5cblx0XHRcdFx0ICAgICAgICBjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBVc2UgVW5zaWduZWRTaG9ydFR5cGUgb3IgVW5zaWduZWRJbnRUeXBlIGZvciBEZXB0aEZvcm1hdCBEZXB0aFRleHR1cmUuJyApO1xuXG5cdFx0XHRcdFx0dGV4dHVyZS50eXBlID0gVW5zaWduZWRTaG9ydFR5cGU7XG5cdFx0XHRcdFx0Z2xUeXBlID0gcGFyYW1UaHJlZVRvR0woIHRleHR1cmUudHlwZSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXB0aCBzdGVuY2lsIHRleHR1cmVzIG5lZWQgdGhlIERFUFRIX1NURU5DSUwgaW50ZXJuYWwgZm9ybWF0XG5cdFx0XHQvLyAoaHR0cHM6Ly93d3cua2hyb25vcy5vcmcvcmVnaXN0cnkvd2ViZ2wvZXh0ZW5zaW9ucy9XRUJHTF9kZXB0aF90ZXh0dXJlLylcblx0XHRcdGlmICggdGV4dHVyZS5mb3JtYXQgPT09IERlcHRoU3RlbmNpbEZvcm1hdCApIHtcblxuXHRcdFx0XHRpbnRlcm5hbEZvcm1hdCA9IF9nbC5ERVBUSF9TVEVOQ0lMO1xuXG5cdFx0XHRcdC8vIFRoZSBlcnJvciBJTlZBTElEX09QRVJBVElPTiBpcyBnZW5lcmF0ZWQgYnkgdGV4SW1hZ2UyRCBpZiBmb3JtYXQgYW5kIGludGVybmFsZm9ybWF0IGFyZVxuXHRcdFx0XHQvLyBERVBUSF9TVEVOQ0lMIGFuZCB0eXBlIGlzIG5vdCBVTlNJR05FRF9JTlRfMjRfOF9XRUJHTC5cblx0XHRcdFx0Ly8gKGh0dHBzOi8vd3d3Lmtocm9ub3Mub3JnL3JlZ2lzdHJ5L3dlYmdsL2V4dGVuc2lvbnMvV0VCR0xfZGVwdGhfdGV4dHVyZS8pXG5cdFx0XHRcdGlmICggdGV4dHVyZS50eXBlICE9PSBVbnNpZ25lZEludDI0OFR5cGUgKSB7XG5cblx0XHRcdFx0ICAgICAgICBjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiBVc2UgVW5zaWduZWRJbnQyNDhUeXBlIGZvciBEZXB0aFN0ZW5jaWxGb3JtYXQgRGVwdGhUZXh0dXJlLicgKTtcblxuXHRcdFx0XHRcdHRleHR1cmUudHlwZSA9IFVuc2lnbmVkSW50MjQ4VHlwZTtcblx0XHRcdFx0XHRnbFR5cGUgPSBwYXJhbVRocmVlVG9HTCggdGV4dHVyZS50eXBlICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdHN0YXRlLnRleEltYWdlMkQoIF9nbC5URVhUVVJFXzJELCAwLCBpbnRlcm5hbEZvcm1hdCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCwgMCwgZ2xGb3JtYXQsIGdsVHlwZSwgbnVsbCApO1xuXG5cdFx0fSBlbHNlIGlmICggdGV4dHVyZS5pc0RhdGFUZXh0dXJlICkge1xuXG5cdFx0XHQvLyB1c2UgbWFudWFsbHkgY3JlYXRlZCBtaXBtYXBzIGlmIGF2YWlsYWJsZVxuXHRcdFx0Ly8gaWYgdGhlcmUgYXJlIG5vIG1hbnVhbCBtaXBtYXBzXG5cdFx0XHQvLyBzZXQgMCBsZXZlbCBtaXBtYXAgYW5kIHRoZW4gdXNlIEdMIHRvIGdlbmVyYXRlIG90aGVyIG1pcG1hcCBsZXZlbHNcblxuXHRcdFx0aWYgKCBtaXBtYXBzLmxlbmd0aCA+IDAgJiYgaXNQb3dlck9mVHdvSW1hZ2UgKSB7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IG1pcG1hcHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRtaXBtYXAgPSBtaXBtYXBzWyBpIF07XG5cdFx0XHRcdFx0c3RhdGUudGV4SW1hZ2UyRCggX2dsLlRFWFRVUkVfMkQsIGksIGdsRm9ybWF0LCBtaXBtYXAud2lkdGgsIG1pcG1hcC5oZWlnaHQsIDAsIGdsRm9ybWF0LCBnbFR5cGUsIG1pcG1hcC5kYXRhICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzID0gZmFsc2U7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0c3RhdGUudGV4SW1hZ2UyRCggX2dsLlRFWFRVUkVfMkQsIDAsIGdsRm9ybWF0LCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0LCAwLCBnbEZvcm1hdCwgZ2xUeXBlLCBpbWFnZS5kYXRhICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSBpZiAoIHRleHR1cmUuaXNDb21wcmVzc2VkVGV4dHVyZSApIHtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IG1pcG1hcHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0bWlwbWFwID0gbWlwbWFwc1sgaSBdO1xuXG5cdFx0XHRcdGlmICggdGV4dHVyZS5mb3JtYXQgIT09IFJHQkFGb3JtYXQgJiYgdGV4dHVyZS5mb3JtYXQgIT09IFJHQkZvcm1hdCApIHtcblxuXHRcdFx0XHRcdGlmICggc3RhdGUuZ2V0Q29tcHJlc3NlZFRleHR1cmVGb3JtYXRzKCkuaW5kZXhPZiggZ2xGb3JtYXQgKSA+IC0gMSApIHtcblxuXHRcdFx0XHRcdFx0c3RhdGUuY29tcHJlc3NlZFRleEltYWdlMkQoIF9nbC5URVhUVVJFXzJELCBpLCBnbEZvcm1hdCwgbWlwbWFwLndpZHRoLCBtaXBtYXAuaGVpZ2h0LCAwLCBtaXBtYXAuZGF0YSApO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0Y29uc29sZS53YXJuKCBcIlRIUkVFLldlYkdMUmVuZGVyZXI6IEF0dGVtcHQgdG8gbG9hZCB1bnN1cHBvcnRlZCBjb21wcmVzc2VkIHRleHR1cmUgZm9ybWF0IGluIC51cGxvYWRUZXh0dXJlKClcIiApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRzdGF0ZS50ZXhJbWFnZTJEKCBfZ2wuVEVYVFVSRV8yRCwgaSwgZ2xGb3JtYXQsIG1pcG1hcC53aWR0aCwgbWlwbWFwLmhlaWdodCwgMCwgZ2xGb3JtYXQsIGdsVHlwZSwgbWlwbWFwLmRhdGEgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIHJlZ3VsYXIgVGV4dHVyZSAoaW1hZ2UsIHZpZGVvLCBjYW52YXMpXG5cblx0XHRcdC8vIHVzZSBtYW51YWxseSBjcmVhdGVkIG1pcG1hcHMgaWYgYXZhaWxhYmxlXG5cdFx0XHQvLyBpZiB0aGVyZSBhcmUgbm8gbWFudWFsIG1pcG1hcHNcblx0XHRcdC8vIHNldCAwIGxldmVsIG1pcG1hcCBhbmQgdGhlbiB1c2UgR0wgdG8gZ2VuZXJhdGUgb3RoZXIgbWlwbWFwIGxldmVsc1xuXG5cdFx0XHRpZiAoIG1pcG1hcHMubGVuZ3RoID4gMCAmJiBpc1Bvd2VyT2ZUd29JbWFnZSApIHtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gbWlwbWFwcy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0XHRcdG1pcG1hcCA9IG1pcG1hcHNbIGkgXTtcblx0XHRcdFx0XHRzdGF0ZS50ZXhJbWFnZTJEKCBfZ2wuVEVYVFVSRV8yRCwgaSwgZ2xGb3JtYXQsIGdsRm9ybWF0LCBnbFR5cGUsIG1pcG1hcCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0ZXh0dXJlLmdlbmVyYXRlTWlwbWFwcyA9IGZhbHNlO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHN0YXRlLnRleEltYWdlMkQoIF9nbC5URVhUVVJFXzJELCAwLCBnbEZvcm1hdCwgZ2xGb3JtYXQsIGdsVHlwZSwgaW1hZ2UgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aWYgKCB0ZXh0dXJlLmdlbmVyYXRlTWlwbWFwcyAmJiBpc1Bvd2VyT2ZUd29JbWFnZSApIF9nbC5nZW5lcmF0ZU1pcG1hcCggX2dsLlRFWFRVUkVfMkQgKTtcblxuXHRcdHRleHR1cmVQcm9wZXJ0aWVzLl9fdmVyc2lvbiA9IHRleHR1cmUudmVyc2lvbjtcblxuXHRcdGlmICggdGV4dHVyZS5vblVwZGF0ZSApIHRleHR1cmUub25VcGRhdGUoIHRleHR1cmUgKTtcblxuXHR9XG5cblx0Ly8gUmVuZGVyIHRhcmdldHNcblxuXHQvLyBTZXR1cCBzdG9yYWdlIGZvciB0YXJnZXQgdGV4dHVyZSBhbmQgYmluZCBpdCB0byBjb3JyZWN0IGZyYW1lYnVmZmVyXG5cdGZ1bmN0aW9uIHNldHVwRnJhbWVCdWZmZXJUZXh0dXJlKCBmcmFtZWJ1ZmZlciwgcmVuZGVyVGFyZ2V0LCBhdHRhY2htZW50LCB0ZXh0dXJlVGFyZ2V0ICkge1xuXG5cdFx0dmFyIGdsRm9ybWF0ID0gcGFyYW1UaHJlZVRvR0woIHJlbmRlclRhcmdldC50ZXh0dXJlLmZvcm1hdCApO1xuXHRcdHZhciBnbFR5cGUgPSBwYXJhbVRocmVlVG9HTCggcmVuZGVyVGFyZ2V0LnRleHR1cmUudHlwZSApO1xuXHRcdHN0YXRlLnRleEltYWdlMkQoIHRleHR1cmVUYXJnZXQsIDAsIGdsRm9ybWF0LCByZW5kZXJUYXJnZXQud2lkdGgsIHJlbmRlclRhcmdldC5oZWlnaHQsIDAsIGdsRm9ybWF0LCBnbFR5cGUsIG51bGwgKTtcblx0XHRfZ2wuYmluZEZyYW1lYnVmZmVyKCBfZ2wuRlJBTUVCVUZGRVIsIGZyYW1lYnVmZmVyICk7XG5cdFx0X2dsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKCBfZ2wuRlJBTUVCVUZGRVIsIGF0dGFjaG1lbnQsIHRleHR1cmVUYXJnZXQsIHByb3BlcnRpZXMuZ2V0KCByZW5kZXJUYXJnZXQudGV4dHVyZSApLl9fd2ViZ2xUZXh0dXJlLCAwICk7XG5cdFx0X2dsLmJpbmRGcmFtZWJ1ZmZlciggX2dsLkZSQU1FQlVGRkVSLCBudWxsICk7XG5cblx0fVxuXG5cdC8vIFNldHVwIHN0b3JhZ2UgZm9yIGludGVybmFsIGRlcHRoL3N0ZW5jaWwgYnVmZmVycyBhbmQgYmluZCB0byBjb3JyZWN0IGZyYW1lYnVmZmVyXG5cdGZ1bmN0aW9uIHNldHVwUmVuZGVyQnVmZmVyU3RvcmFnZSggcmVuZGVyYnVmZmVyLCByZW5kZXJUYXJnZXQgKSB7XG5cblx0XHRfZ2wuYmluZFJlbmRlcmJ1ZmZlciggX2dsLlJFTkRFUkJVRkZFUiwgcmVuZGVyYnVmZmVyICk7XG5cblx0XHRpZiAoIHJlbmRlclRhcmdldC5kZXB0aEJ1ZmZlciAmJiAhIHJlbmRlclRhcmdldC5zdGVuY2lsQnVmZmVyICkge1xuXG5cdFx0XHRfZ2wucmVuZGVyYnVmZmVyU3RvcmFnZSggX2dsLlJFTkRFUkJVRkZFUiwgX2dsLkRFUFRIX0NPTVBPTkVOVDE2LCByZW5kZXJUYXJnZXQud2lkdGgsIHJlbmRlclRhcmdldC5oZWlnaHQgKTtcblx0XHRcdF9nbC5mcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlciggX2dsLkZSQU1FQlVGRkVSLCBfZ2wuREVQVEhfQVRUQUNITUVOVCwgX2dsLlJFTkRFUkJVRkZFUiwgcmVuZGVyYnVmZmVyICk7XG5cblx0XHR9IGVsc2UgaWYgKCByZW5kZXJUYXJnZXQuZGVwdGhCdWZmZXIgJiYgcmVuZGVyVGFyZ2V0LnN0ZW5jaWxCdWZmZXIgKSB7XG5cblx0XHRcdF9nbC5yZW5kZXJidWZmZXJTdG9yYWdlKCBfZ2wuUkVOREVSQlVGRkVSLCBfZ2wuREVQVEhfU1RFTkNJTCwgcmVuZGVyVGFyZ2V0LndpZHRoLCByZW5kZXJUYXJnZXQuaGVpZ2h0ICk7XG5cdFx0XHRfZ2wuZnJhbWVidWZmZXJSZW5kZXJidWZmZXIoIF9nbC5GUkFNRUJVRkZFUiwgX2dsLkRFUFRIX1NURU5DSUxfQVRUQUNITUVOVCwgX2dsLlJFTkRFUkJVRkZFUiwgcmVuZGVyYnVmZmVyICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBGSVhNRTogV2UgZG9uJ3Qgc3VwcG9ydCAhZGVwdGggIXN0ZW5jaWxcblx0XHRcdF9nbC5yZW5kZXJidWZmZXJTdG9yYWdlKCBfZ2wuUkVOREVSQlVGRkVSLCBfZ2wuUkdCQTQsIHJlbmRlclRhcmdldC53aWR0aCwgcmVuZGVyVGFyZ2V0LmhlaWdodCApO1xuXG5cdFx0fVxuXG5cdFx0X2dsLmJpbmRSZW5kZXJidWZmZXIoIF9nbC5SRU5ERVJCVUZGRVIsIG51bGwgKTtcblxuXHR9XG5cblx0Ly8gU2V0dXAgcmVzb3VyY2VzIGZvciBhIERlcHRoIFRleHR1cmUgZm9yIGEgRkJPIChuZWVkcyBhbiBleHRlbnNpb24pXG5cdGZ1bmN0aW9uIHNldHVwRGVwdGhUZXh0dXJlKCBmcmFtZWJ1ZmZlciwgcmVuZGVyVGFyZ2V0ICkge1xuXG5cdFx0dmFyIGlzQ3ViZSA9ICggcmVuZGVyVGFyZ2V0ICYmIHJlbmRlclRhcmdldC5pc1dlYkdMUmVuZGVyVGFyZ2V0Q3ViZSApO1xuXHRcdGlmICggaXNDdWJlICkgdGhyb3cgbmV3IEVycm9yKCdEZXB0aCBUZXh0dXJlIHdpdGggY3ViZSByZW5kZXIgdGFyZ2V0cyBpcyBub3Qgc3VwcG9ydGVkIScpO1xuXG5cdFx0X2dsLmJpbmRGcmFtZWJ1ZmZlciggX2dsLkZSQU1FQlVGRkVSLCBmcmFtZWJ1ZmZlciApO1xuXG5cdFx0aWYgKCAhKCByZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlICYmIHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUuaXNEZXB0aFRleHR1cmUgKSApIHtcblxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdyZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgVEhSRUUuRGVwdGhUZXh0dXJlJyk7XG5cblx0XHR9XG5cblx0XHQvLyB1cGxvYWQgYW4gZW1wdHkgZGVwdGggdGV4dHVyZSB3aXRoIGZyYW1lYnVmZmVyIHNpemVcblx0XHRpZiAoICFwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0LmRlcHRoVGV4dHVyZSApLl9fd2ViZ2xUZXh0dXJlIHx8XG5cdFx0XHRcdHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUuaW1hZ2Uud2lkdGggIT09IHJlbmRlclRhcmdldC53aWR0aCB8fFxuXHRcdFx0XHRyZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlLmltYWdlLmhlaWdodCAhPT0gcmVuZGVyVGFyZ2V0LmhlaWdodCApIHtcblx0XHRcdHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUuaW1hZ2Uud2lkdGggPSByZW5kZXJUYXJnZXQud2lkdGg7XG5cdFx0XHRyZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlLmltYWdlLmhlaWdodCA9IHJlbmRlclRhcmdldC5oZWlnaHQ7XG5cdFx0XHRyZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRzZXRUZXh0dXJlMkQoIHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUsIDAgKTtcblxuXHRcdHZhciB3ZWJnbERlcHRoVGV4dHVyZSA9IHByb3BlcnRpZXMuZ2V0KCByZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlICkuX193ZWJnbFRleHR1cmU7XG5cblx0XHRpZiAoIHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUuZm9ybWF0ID09PSBEZXB0aEZvcm1hdCApIHtcblxuXHRcdFx0X2dsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKCBfZ2wuRlJBTUVCVUZGRVIsIF9nbC5ERVBUSF9BVFRBQ0hNRU5ULCBfZ2wuVEVYVFVSRV8yRCwgd2ViZ2xEZXB0aFRleHR1cmUsIDAgKTtcblxuXHRcdH0gZWxzZSBpZiAoIHJlbmRlclRhcmdldC5kZXB0aFRleHR1cmUuZm9ybWF0ID09PSBEZXB0aFN0ZW5jaWxGb3JtYXQgKSB7XG5cblx0XHRcdF9nbC5mcmFtZWJ1ZmZlclRleHR1cmUyRCggX2dsLkZSQU1FQlVGRkVSLCBfZ2wuREVQVEhfU1RFTkNJTF9BVFRBQ0hNRU5ULCBfZ2wuVEVYVFVSRV8yRCwgd2ViZ2xEZXB0aFRleHR1cmUsIDAgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRocm93IG5ldyBFcnJvcignVW5rbm93biBkZXB0aFRleHR1cmUgZm9ybWF0JylcblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gU2V0dXAgR0wgcmVzb3VyY2VzIGZvciBhIG5vbi10ZXh0dXJlIGRlcHRoIGJ1ZmZlclxuXHRmdW5jdGlvbiBzZXR1cERlcHRoUmVuZGVyYnVmZmVyKCByZW5kZXJUYXJnZXQgKSB7XG5cblx0XHR2YXIgcmVuZGVyVGFyZ2V0UHJvcGVydGllcyA9IHByb3BlcnRpZXMuZ2V0KCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdHZhciBpc0N1YmUgPSAoIHJlbmRlclRhcmdldC5pc1dlYkdMUmVuZGVyVGFyZ2V0Q3ViZSA9PT0gdHJ1ZSApO1xuXG5cdFx0aWYgKCByZW5kZXJUYXJnZXQuZGVwdGhUZXh0dXJlICkge1xuXG5cdFx0XHRpZiAoIGlzQ3ViZSApIHRocm93IG5ldyBFcnJvcigndGFyZ2V0LmRlcHRoVGV4dHVyZSBub3Qgc3VwcG9ydGVkIGluIEN1YmUgcmVuZGVyIHRhcmdldHMnKTtcblxuXHRcdFx0c2V0dXBEZXB0aFRleHR1cmUoIHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbEZyYW1lYnVmZmVyLCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGlmICggaXNDdWJlICkge1xuXG5cdFx0XHRcdHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbERlcHRoYnVmZmVyID0gW107XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0XHRcdF9nbC5iaW5kRnJhbWVidWZmZXIoIF9nbC5GUkFNRUJVRkZFUiwgcmVuZGVyVGFyZ2V0UHJvcGVydGllcy5fX3dlYmdsRnJhbWVidWZmZXJbIGkgXSApO1xuXHRcdFx0XHRcdHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbERlcHRoYnVmZmVyWyBpIF0gPSBfZ2wuY3JlYXRlUmVuZGVyYnVmZmVyKCk7XG5cdFx0XHRcdFx0c2V0dXBSZW5kZXJCdWZmZXJTdG9yYWdlKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xEZXB0aGJ1ZmZlclsgaSBdLCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0X2dsLmJpbmRGcmFtZWJ1ZmZlciggX2dsLkZSQU1FQlVGRkVSLCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xGcmFtZWJ1ZmZlciApO1xuXHRcdFx0XHRyZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xEZXB0aGJ1ZmZlciA9IF9nbC5jcmVhdGVSZW5kZXJidWZmZXIoKTtcblx0XHRcdFx0c2V0dXBSZW5kZXJCdWZmZXJTdG9yYWdlKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xEZXB0aGJ1ZmZlciwgcmVuZGVyVGFyZ2V0ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdF9nbC5iaW5kRnJhbWVidWZmZXIoIF9nbC5GUkFNRUJVRkZFUiwgbnVsbCApO1xuXG5cdH1cblxuXHQvLyBTZXQgdXAgR0wgcmVzb3VyY2VzIGZvciB0aGUgcmVuZGVyIHRhcmdldFxuXHRmdW5jdGlvbiBzZXR1cFJlbmRlclRhcmdldCggcmVuZGVyVGFyZ2V0ICkge1xuXG5cdFx0dmFyIHJlbmRlclRhcmdldFByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0ICk7XG5cdFx0dmFyIHRleHR1cmVQcm9wZXJ0aWVzID0gcHJvcGVydGllcy5nZXQoIHJlbmRlclRhcmdldC50ZXh0dXJlICk7XG5cblx0XHRyZW5kZXJUYXJnZXQuYWRkRXZlbnRMaXN0ZW5lciggJ2Rpc3Bvc2UnLCBvblJlbmRlclRhcmdldERpc3Bvc2UgKTtcblxuXHRcdHRleHR1cmVQcm9wZXJ0aWVzLl9fd2ViZ2xUZXh0dXJlID0gX2dsLmNyZWF0ZVRleHR1cmUoKTtcblxuXHRcdGluZm9NZW1vcnkudGV4dHVyZXMgKys7XG5cblx0XHR2YXIgaXNDdWJlID0gKCByZW5kZXJUYXJnZXQuaXNXZWJHTFJlbmRlclRhcmdldEN1YmUgPT09IHRydWUgKTtcblx0XHR2YXIgaXNUYXJnZXRQb3dlck9mVHdvID0gaXNQb3dlck9mVHdvKCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdC8vIFNldHVwIGZyYW1lYnVmZmVyXG5cblx0XHRpZiAoIGlzQ3ViZSApIHtcblxuXHRcdFx0cmVuZGVyVGFyZ2V0UHJvcGVydGllcy5fX3dlYmdsRnJhbWVidWZmZXIgPSBbXTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0XHRyZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xGcmFtZWJ1ZmZlclsgaSBdID0gX2dsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHJlbmRlclRhcmdldFByb3BlcnRpZXMuX193ZWJnbEZyYW1lYnVmZmVyID0gX2dsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG5cblx0XHR9XG5cblx0XHQvLyBTZXR1cCBjb2xvciBidWZmZXJcblxuXHRcdGlmICggaXNDdWJlICkge1xuXG5cdFx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggX2dsLlRFWFRVUkVfQ1VCRV9NQVAsIHRleHR1cmVQcm9wZXJ0aWVzLl9fd2ViZ2xUZXh0dXJlICk7XG5cdFx0XHRzZXRUZXh0dXJlUGFyYW1ldGVycyggX2dsLlRFWFRVUkVfQ1VCRV9NQVAsIHJlbmRlclRhcmdldC50ZXh0dXJlLCBpc1RhcmdldFBvd2VyT2ZUd28gKTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgNjsgaSArKyApIHtcblxuXHRcdFx0XHRzZXR1cEZyYW1lQnVmZmVyVGV4dHVyZSggcmVuZGVyVGFyZ2V0UHJvcGVydGllcy5fX3dlYmdsRnJhbWVidWZmZXJbIGkgXSwgcmVuZGVyVGFyZ2V0LCBfZ2wuQ09MT1JfQVRUQUNITUVOVDAsIF9nbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyBpICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCByZW5kZXJUYXJnZXQudGV4dHVyZS5nZW5lcmF0ZU1pcG1hcHMgJiYgaXNUYXJnZXRQb3dlck9mVHdvICkgX2dsLmdlbmVyYXRlTWlwbWFwKCBfZ2wuVEVYVFVSRV9DVUJFX01BUCApO1xuXHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIF9nbC5URVhUVVJFX0NVQkVfTUFQLCBudWxsICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRzdGF0ZS5iaW5kVGV4dHVyZSggX2dsLlRFWFRVUkVfMkQsIHRleHR1cmVQcm9wZXJ0aWVzLl9fd2ViZ2xUZXh0dXJlICk7XG5cdFx0XHRzZXRUZXh0dXJlUGFyYW1ldGVycyggX2dsLlRFWFRVUkVfMkQsIHJlbmRlclRhcmdldC50ZXh0dXJlLCBpc1RhcmdldFBvd2VyT2ZUd28gKTtcblx0XHRcdHNldHVwRnJhbWVCdWZmZXJUZXh0dXJlKCByZW5kZXJUYXJnZXRQcm9wZXJ0aWVzLl9fd2ViZ2xGcmFtZWJ1ZmZlciwgcmVuZGVyVGFyZ2V0LCBfZ2wuQ09MT1JfQVRUQUNITUVOVDAsIF9nbC5URVhUVVJFXzJEICk7XG5cblx0XHRcdGlmICggcmVuZGVyVGFyZ2V0LnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzICYmIGlzVGFyZ2V0UG93ZXJPZlR3byApIF9nbC5nZW5lcmF0ZU1pcG1hcCggX2dsLlRFWFRVUkVfMkQgKTtcblx0XHRcdHN0YXRlLmJpbmRUZXh0dXJlKCBfZ2wuVEVYVFVSRV8yRCwgbnVsbCApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gU2V0dXAgZGVwdGggYW5kIHN0ZW5jaWwgYnVmZmVyc1xuXG5cdFx0aWYgKCByZW5kZXJUYXJnZXQuZGVwdGhCdWZmZXIgKSB7XG5cblx0XHRcdHNldHVwRGVwdGhSZW5kZXJidWZmZXIoIHJlbmRlclRhcmdldCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiB1cGRhdGVSZW5kZXJUYXJnZXRNaXBtYXAoIHJlbmRlclRhcmdldCApIHtcblxuXHRcdHZhciB0ZXh0dXJlID0gcmVuZGVyVGFyZ2V0LnRleHR1cmU7XG5cblx0XHRpZiAoIHRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzICYmIGlzUG93ZXJPZlR3byggcmVuZGVyVGFyZ2V0ICkgJiZcblx0XHRcdFx0dGV4dHVyZS5taW5GaWx0ZXIgIT09IE5lYXJlc3RGaWx0ZXIgJiZcblx0XHRcdFx0dGV4dHVyZS5taW5GaWx0ZXIgIT09IExpbmVhckZpbHRlciApIHtcblxuXHRcdFx0dmFyIHRhcmdldCA9IChyZW5kZXJUYXJnZXQgJiYgcmVuZGVyVGFyZ2V0LmlzV2ViR0xSZW5kZXJUYXJnZXRDdWJlKSA/IF9nbC5URVhUVVJFX0NVQkVfTUFQIDogX2dsLlRFWFRVUkVfMkQ7XG5cdFx0XHR2YXIgd2ViZ2xUZXh0dXJlID0gcHJvcGVydGllcy5nZXQoIHRleHR1cmUgKS5fX3dlYmdsVGV4dHVyZTtcblxuXHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIHRhcmdldCwgd2ViZ2xUZXh0dXJlICk7XG5cdFx0XHRfZ2wuZ2VuZXJhdGVNaXBtYXAoIHRhcmdldCApO1xuXHRcdFx0c3RhdGUuYmluZFRleHR1cmUoIHRhcmdldCwgbnVsbCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHR0aGlzLnNldFRleHR1cmUyRCA9IHNldFRleHR1cmUyRDtcblx0dGhpcy5zZXRUZXh0dXJlQ3ViZSA9IHNldFRleHR1cmVDdWJlO1xuXHR0aGlzLnNldFRleHR1cmVDdWJlRHluYW1pYyA9IHNldFRleHR1cmVDdWJlRHluYW1pYztcblx0dGhpcy5zZXR1cFJlbmRlclRhcmdldCA9IHNldHVwUmVuZGVyVGFyZ2V0O1xuXHR0aGlzLnVwZGF0ZVJlbmRlclRhcmdldE1pcG1hcCA9IHVwZGF0ZVJlbmRlclRhcmdldE1pcG1hcDtcblxufVxuXG4vKipcbiAqIEBhdXRob3IgZm9yZGFjaW91cyAvIGZvcmRhY2lvdXMuZ2l0aHViLmlvXG4gKi9cblxuZnVuY3Rpb24gV2ViR0xQcm9wZXJ0aWVzKCkge1xuXG5cdHZhciBwcm9wZXJ0aWVzID0ge307XG5cblx0ZnVuY3Rpb24gZ2V0KCBvYmplY3QgKSB7XG5cblx0XHR2YXIgdXVpZCA9IG9iamVjdC51dWlkO1xuXHRcdHZhciBtYXAgPSBwcm9wZXJ0aWVzWyB1dWlkIF07XG5cblx0XHRpZiAoIG1hcCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRtYXAgPSB7fTtcblx0XHRcdHByb3BlcnRpZXNbIHV1aWQgXSA9IG1hcDtcblxuXHRcdH1cblxuXHRcdHJldHVybiBtYXA7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHJlbW92ZSggb2JqZWN0ICkge1xuXG5cdFx0ZGVsZXRlIHByb3BlcnRpZXNbIG9iamVjdC51dWlkIF07XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGNsZWFyKCkge1xuXG5cdFx0cHJvcGVydGllcyA9IHt9O1xuXG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdGdldDogZ2V0LFxuXHRcdHJlbW92ZTogcmVtb3ZlLFxuXHRcdGNsZWFyOiBjbGVhclxuXHR9O1xuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBXZWJHTFN0YXRlKCBnbCwgZXh0ZW5zaW9ucywgcGFyYW1UaHJlZVRvR0wgKSB7XG5cblx0ZnVuY3Rpb24gQ29sb3JCdWZmZXIoKSB7XG5cblx0XHR2YXIgbG9ja2VkID0gZmFsc2U7XG5cblx0XHR2YXIgY29sb3IgPSBuZXcgVmVjdG9yNCgpO1xuXHRcdHZhciBjdXJyZW50Q29sb3JNYXNrID0gbnVsbDtcblx0XHR2YXIgY3VycmVudENvbG9yQ2xlYXIgPSBuZXcgVmVjdG9yNCgpO1xuXG5cdFx0cmV0dXJuIHtcblxuXHRcdFx0c2V0TWFzazogZnVuY3Rpb24gKCBjb2xvck1hc2sgKSB7XG5cblx0XHRcdFx0aWYgKCBjdXJyZW50Q29sb3JNYXNrICE9PSBjb2xvck1hc2sgJiYgISBsb2NrZWQgKSB7XG5cblx0XHRcdFx0XHRnbC5jb2xvck1hc2soIGNvbG9yTWFzaywgY29sb3JNYXNrLCBjb2xvck1hc2ssIGNvbG9yTWFzayApO1xuXHRcdFx0XHRcdGN1cnJlbnRDb2xvck1hc2sgPSBjb2xvck1hc2s7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LFxuXG5cdFx0XHRzZXRMb2NrZWQ6IGZ1bmN0aW9uICggbG9jayApIHtcblxuXHRcdFx0XHRsb2NrZWQgPSBsb2NrO1xuXG5cdFx0XHR9LFxuXG5cdFx0XHRzZXRDbGVhcjogZnVuY3Rpb24gKCByLCBnLCBiLCBhLCBwcmVtdWx0aXBsaWVkQWxwaGEgKSB7XG5cblx0XHRcdFx0aWYgKCBwcmVtdWx0aXBsaWVkQWxwaGEgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0XHRyICo9IGE7IGcgKj0gYTsgYiAqPSBhO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb2xvci5zZXQoIHIsIGcsIGIsIGEgKTtcblxuXHRcdFx0XHRpZiAoIGN1cnJlbnRDb2xvckNsZWFyLmVxdWFscyggY29sb3IgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRnbC5jbGVhckNvbG9yKCByLCBnLCBiLCBhICk7XG5cdFx0XHRcdFx0Y3VycmVudENvbG9yQ2xlYXIuY29weSggY29sb3IgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0bG9ja2VkID0gZmFsc2U7XG5cblx0XHRcdFx0Y3VycmVudENvbG9yTWFzayA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnRDb2xvckNsZWFyLnNldCggMCwgMCwgMCwgMSApO1xuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdH1cblxuXHRmdW5jdGlvbiBEZXB0aEJ1ZmZlcigpIHtcblxuXHRcdHZhciBsb2NrZWQgPSBmYWxzZTtcblxuXHRcdHZhciBjdXJyZW50RGVwdGhNYXNrID0gbnVsbDtcblx0XHR2YXIgY3VycmVudERlcHRoRnVuYyA9IG51bGw7XG5cdFx0dmFyIGN1cnJlbnREZXB0aENsZWFyID0gbnVsbDtcblxuXHRcdHJldHVybiB7XG5cblx0XHRcdHNldFRlc3Q6IGZ1bmN0aW9uICggZGVwdGhUZXN0ICkge1xuXG5cdFx0XHRcdGlmICggZGVwdGhUZXN0ICkge1xuXG5cdFx0XHRcdFx0ZW5hYmxlKCBnbC5ERVBUSF9URVNUICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGRpc2FibGUoIGdsLkRFUFRIX1RFU1QgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHNldE1hc2s6IGZ1bmN0aW9uICggZGVwdGhNYXNrICkge1xuXG5cdFx0XHRcdGlmICggY3VycmVudERlcHRoTWFzayAhPT0gZGVwdGhNYXNrICYmICEgbG9ja2VkICkge1xuXG5cdFx0XHRcdFx0Z2wuZGVwdGhNYXNrKCBkZXB0aE1hc2sgKTtcblx0XHRcdFx0XHRjdXJyZW50RGVwdGhNYXNrID0gZGVwdGhNYXNrO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSxcblxuXHRcdFx0c2V0RnVuYzogZnVuY3Rpb24gKCBkZXB0aEZ1bmMgKSB7XG5cblx0XHRcdFx0aWYgKCBjdXJyZW50RGVwdGhGdW5jICE9PSBkZXB0aEZ1bmMgKSB7XG5cblx0XHRcdFx0XHRpZiAoIGRlcHRoRnVuYyApIHtcblxuXHRcdFx0XHRcdFx0c3dpdGNoICggZGVwdGhGdW5jICkge1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgTmV2ZXJEZXB0aDpcblxuXHRcdFx0XHRcdFx0XHRcdGdsLmRlcHRoRnVuYyggZ2wuTkVWRVIgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIEFsd2F5c0RlcHRoOlxuXG5cdFx0XHRcdFx0XHRcdFx0Z2wuZGVwdGhGdW5jKCBnbC5BTFdBWVMgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIExlc3NEZXB0aDpcblxuXHRcdFx0XHRcdFx0XHRcdGdsLmRlcHRoRnVuYyggZ2wuTEVTUyApO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgTGVzc0VxdWFsRGVwdGg6XG5cblx0XHRcdFx0XHRcdFx0XHRnbC5kZXB0aEZ1bmMoIGdsLkxFUVVBTCApO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgRXF1YWxEZXB0aDpcblxuXHRcdFx0XHRcdFx0XHRcdGdsLmRlcHRoRnVuYyggZ2wuRVFVQUwgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIEdyZWF0ZXJFcXVhbERlcHRoOlxuXG5cdFx0XHRcdFx0XHRcdFx0Z2wuZGVwdGhGdW5jKCBnbC5HRVFVQUwgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIEdyZWF0ZXJEZXB0aDpcblxuXHRcdFx0XHRcdFx0XHRcdGdsLmRlcHRoRnVuYyggZ2wuR1JFQVRFUiApO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRcdGNhc2UgTm90RXF1YWxEZXB0aDpcblxuXHRcdFx0XHRcdFx0XHRcdGdsLmRlcHRoRnVuYyggZ2wuTk9URVFVQUwgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXG5cdFx0XHRcdFx0XHRcdFx0Z2wuZGVwdGhGdW5jKCBnbC5MRVFVQUwgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0Z2wuZGVwdGhGdW5jKCBnbC5MRVFVQUwgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGN1cnJlbnREZXB0aEZ1bmMgPSBkZXB0aEZ1bmM7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LFxuXG5cdFx0XHRzZXRMb2NrZWQ6IGZ1bmN0aW9uICggbG9jayApIHtcblxuXHRcdFx0XHRsb2NrZWQgPSBsb2NrO1xuXG5cdFx0XHR9LFxuXG5cdFx0XHRzZXRDbGVhcjogZnVuY3Rpb24gKCBkZXB0aCApIHtcblxuXHRcdFx0XHRpZiAoIGN1cnJlbnREZXB0aENsZWFyICE9PSBkZXB0aCApIHtcblxuXHRcdFx0XHRcdGdsLmNsZWFyRGVwdGgoIGRlcHRoICk7XG5cdFx0XHRcdFx0Y3VycmVudERlcHRoQ2xlYXIgPSBkZXB0aDtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0bG9ja2VkID0gZmFsc2U7XG5cblx0XHRcdFx0Y3VycmVudERlcHRoTWFzayA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnREZXB0aEZ1bmMgPSBudWxsO1xuXHRcdFx0XHRjdXJyZW50RGVwdGhDbGVhciA9IG51bGw7XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fVxuXG5cdGZ1bmN0aW9uIFN0ZW5jaWxCdWZmZXIoKSB7XG5cblx0XHR2YXIgbG9ja2VkID0gZmFsc2U7XG5cblx0XHR2YXIgY3VycmVudFN0ZW5jaWxNYXNrID0gbnVsbDtcblx0XHR2YXIgY3VycmVudFN0ZW5jaWxGdW5jID0gbnVsbDtcblx0XHR2YXIgY3VycmVudFN0ZW5jaWxSZWYgPSBudWxsO1xuXHRcdHZhciBjdXJyZW50U3RlbmNpbEZ1bmNNYXNrID0gbnVsbDtcblx0XHR2YXIgY3VycmVudFN0ZW5jaWxGYWlsID0gbnVsbDtcblx0XHR2YXIgY3VycmVudFN0ZW5jaWxaRmFpbCA9IG51bGw7XG5cdFx0dmFyIGN1cnJlbnRTdGVuY2lsWlBhc3MgPSBudWxsO1xuXHRcdHZhciBjdXJyZW50U3RlbmNpbENsZWFyID0gbnVsbDtcblxuXHRcdHJldHVybiB7XG5cblx0XHRcdHNldFRlc3Q6IGZ1bmN0aW9uICggc3RlbmNpbFRlc3QgKSB7XG5cblx0XHRcdFx0aWYgKCBzdGVuY2lsVGVzdCApIHtcblxuXHRcdFx0XHRcdGVuYWJsZSggZ2wuU1RFTkNJTF9URVNUICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGRpc2FibGUoIGdsLlNURU5DSUxfVEVTVCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSxcblxuXHRcdFx0c2V0TWFzazogZnVuY3Rpb24gKCBzdGVuY2lsTWFzayApIHtcblxuXHRcdFx0XHRpZiAoIGN1cnJlbnRTdGVuY2lsTWFzayAhPT0gc3RlbmNpbE1hc2sgJiYgISBsb2NrZWQgKSB7XG5cblx0XHRcdFx0XHRnbC5zdGVuY2lsTWFzayggc3RlbmNpbE1hc2sgKTtcblx0XHRcdFx0XHRjdXJyZW50U3RlbmNpbE1hc2sgPSBzdGVuY2lsTWFzaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHNldEZ1bmM6IGZ1bmN0aW9uICggc3RlbmNpbEZ1bmMsIHN0ZW5jaWxSZWYsIHN0ZW5jaWxNYXNrICkge1xuXG5cdFx0XHRcdGlmICggY3VycmVudFN0ZW5jaWxGdW5jICE9PSBzdGVuY2lsRnVuYyB8fFxuXHRcdFx0XHQgICAgIGN1cnJlbnRTdGVuY2lsUmVmIFx0IT09IHN0ZW5jaWxSZWYgXHR8fFxuXHRcdFx0XHQgICAgIGN1cnJlbnRTdGVuY2lsRnVuY01hc2sgIT09IHN0ZW5jaWxNYXNrICkge1xuXG5cdFx0XHRcdFx0Z2wuc3RlbmNpbEZ1bmMoIHN0ZW5jaWxGdW5jLCBzdGVuY2lsUmVmLCBzdGVuY2lsTWFzayApO1xuXG5cdFx0XHRcdFx0Y3VycmVudFN0ZW5jaWxGdW5jID0gc3RlbmNpbEZ1bmM7XG5cdFx0XHRcdFx0Y3VycmVudFN0ZW5jaWxSZWYgPSBzdGVuY2lsUmVmO1xuXHRcdFx0XHRcdGN1cnJlbnRTdGVuY2lsRnVuY01hc2sgPSBzdGVuY2lsTWFzaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHNldE9wOiBmdW5jdGlvbiAoIHN0ZW5jaWxGYWlsLCBzdGVuY2lsWkZhaWwsIHN0ZW5jaWxaUGFzcyApIHtcblxuXHRcdFx0XHRpZiAoIGN1cnJlbnRTdGVuY2lsRmFpbFx0ICE9PSBzdGVuY2lsRmFpbCBcdHx8XG5cdFx0XHRcdCAgICAgY3VycmVudFN0ZW5jaWxaRmFpbCAhPT0gc3RlbmNpbFpGYWlsIHx8XG5cdFx0XHRcdCAgICAgY3VycmVudFN0ZW5jaWxaUGFzcyAhPT0gc3RlbmNpbFpQYXNzICkge1xuXG5cdFx0XHRcdFx0Z2wuc3RlbmNpbE9wKCBzdGVuY2lsRmFpbCwgc3RlbmNpbFpGYWlsLCBzdGVuY2lsWlBhc3MgKTtcblxuXHRcdFx0XHRcdGN1cnJlbnRTdGVuY2lsRmFpbCA9IHN0ZW5jaWxGYWlsO1xuXHRcdFx0XHRcdGN1cnJlbnRTdGVuY2lsWkZhaWwgPSBzdGVuY2lsWkZhaWw7XG5cdFx0XHRcdFx0Y3VycmVudFN0ZW5jaWxaUGFzcyA9IHN0ZW5jaWxaUGFzcztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0sXG5cblx0XHRcdHNldExvY2tlZDogZnVuY3Rpb24gKCBsb2NrICkge1xuXG5cdFx0XHRcdGxvY2tlZCA9IGxvY2s7XG5cblx0XHRcdH0sXG5cblx0XHRcdHNldENsZWFyOiBmdW5jdGlvbiAoIHN0ZW5jaWwgKSB7XG5cblx0XHRcdFx0aWYgKCBjdXJyZW50U3RlbmNpbENsZWFyICE9PSBzdGVuY2lsICkge1xuXG5cdFx0XHRcdFx0Z2wuY2xlYXJTdGVuY2lsKCBzdGVuY2lsICk7XG5cdFx0XHRcdFx0Y3VycmVudFN0ZW5jaWxDbGVhciA9IHN0ZW5jaWw7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LFxuXG5cdFx0XHRyZXNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRcdGxvY2tlZCA9IGZhbHNlO1xuXG5cdFx0XHRcdGN1cnJlbnRTdGVuY2lsTWFzayA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnRTdGVuY2lsRnVuYyA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnRTdGVuY2lsUmVmID0gbnVsbDtcblx0XHRcdFx0Y3VycmVudFN0ZW5jaWxGdW5jTWFzayA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnRTdGVuY2lsRmFpbCA9IG51bGw7XG5cdFx0XHRcdGN1cnJlbnRTdGVuY2lsWkZhaWwgPSBudWxsO1xuXHRcdFx0XHRjdXJyZW50U3RlbmNpbFpQYXNzID0gbnVsbDtcblx0XHRcdFx0Y3VycmVudFN0ZW5jaWxDbGVhciA9IG51bGw7XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fVxuXG5cdC8vXG5cblx0dmFyIGNvbG9yQnVmZmVyID0gbmV3IENvbG9yQnVmZmVyKCk7XG5cdHZhciBkZXB0aEJ1ZmZlciA9IG5ldyBEZXB0aEJ1ZmZlcigpO1xuXHR2YXIgc3RlbmNpbEJ1ZmZlciA9IG5ldyBTdGVuY2lsQnVmZmVyKCk7XG5cblx0dmFyIG1heFZlcnRleEF0dHJpYnV0ZXMgPSBnbC5nZXRQYXJhbWV0ZXIoIGdsLk1BWF9WRVJURVhfQVRUUklCUyApO1xuXHR2YXIgbmV3QXR0cmlidXRlcyA9IG5ldyBVaW50OEFycmF5KCBtYXhWZXJ0ZXhBdHRyaWJ1dGVzICk7XG5cdHZhciBlbmFibGVkQXR0cmlidXRlcyA9IG5ldyBVaW50OEFycmF5KCBtYXhWZXJ0ZXhBdHRyaWJ1dGVzICk7XG5cdHZhciBhdHRyaWJ1dGVEaXZpc29ycyA9IG5ldyBVaW50OEFycmF5KCBtYXhWZXJ0ZXhBdHRyaWJ1dGVzICk7XG5cblx0dmFyIGNhcGFiaWxpdGllcyA9IHt9O1xuXG5cdHZhciBjb21wcmVzc2VkVGV4dHVyZUZvcm1hdHMgPSBudWxsO1xuXG5cdHZhciBjdXJyZW50QmxlbmRpbmcgPSBudWxsO1xuXHR2YXIgY3VycmVudEJsZW5kRXF1YXRpb24gPSBudWxsO1xuXHR2YXIgY3VycmVudEJsZW5kU3JjID0gbnVsbDtcblx0dmFyIGN1cnJlbnRCbGVuZERzdCA9IG51bGw7XG5cdHZhciBjdXJyZW50QmxlbmRFcXVhdGlvbkFscGhhID0gbnVsbDtcblx0dmFyIGN1cnJlbnRCbGVuZFNyY0FscGhhID0gbnVsbDtcblx0dmFyIGN1cnJlbnRCbGVuZERzdEFscGhhID0gbnVsbDtcblx0dmFyIGN1cnJlbnRQcmVtdWx0aXBsZWRBbHBoYSA9IGZhbHNlO1xuXG5cdHZhciBjdXJyZW50RmxpcFNpZGVkID0gbnVsbDtcblx0dmFyIGN1cnJlbnRDdWxsRmFjZSA9IG51bGw7XG5cblx0dmFyIGN1cnJlbnRMaW5lV2lkdGggPSBudWxsO1xuXG5cdHZhciBjdXJyZW50UG9seWdvbk9mZnNldEZhY3RvciA9IG51bGw7XG5cdHZhciBjdXJyZW50UG9seWdvbk9mZnNldFVuaXRzID0gbnVsbDtcblxuXHR2YXIgY3VycmVudFNjaXNzb3JUZXN0ID0gbnVsbDtcblxuXHR2YXIgbWF4VGV4dHVyZXMgPSBnbC5nZXRQYXJhbWV0ZXIoIGdsLk1BWF9URVhUVVJFX0lNQUdFX1VOSVRTICk7XG5cblx0dmFyIHZlcnNpb24gPSBwYXJzZUZsb2F0KCAvXldlYkdMXFwgKFswLTldKS8uZXhlYyggZ2wuZ2V0UGFyYW1ldGVyKCBnbC5WRVJTSU9OICkgKVsgMSBdICk7XG5cdHZhciBsaW5lV2lkdGhBdmFpbGFibGUgPSBwYXJzZUZsb2F0KCB2ZXJzaW9uICkgPj0gMS4wO1xuXG5cdHZhciBjdXJyZW50VGV4dHVyZVNsb3QgPSBudWxsO1xuXHR2YXIgY3VycmVudEJvdW5kVGV4dHVyZXMgPSB7fTtcblxuXHR2YXIgY3VycmVudFNjaXNzb3IgPSBuZXcgVmVjdG9yNCgpO1xuXHR2YXIgY3VycmVudFZpZXdwb3J0ID0gbmV3IFZlY3RvcjQoKTtcblxuXHRmdW5jdGlvbiBjcmVhdGVUZXh0dXJlKCB0eXBlLCB0YXJnZXQsIGNvdW50ICkge1xuXG5cdFx0dmFyIGRhdGEgPSBuZXcgVWludDhBcnJheSggNCApOyAvLyA0IGlzIHJlcXVpcmVkIHRvIG1hdGNoIGRlZmF1bHQgdW5wYWNrIGFsaWdubWVudCBvZiA0LlxuXHRcdHZhciB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuXG5cdFx0Z2wuYmluZFRleHR1cmUoIHR5cGUsIHRleHR1cmUgKTtcblx0XHRnbC50ZXhQYXJhbWV0ZXJpKCB0eXBlLCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QgKTtcblx0XHRnbC50ZXhQYXJhbWV0ZXJpKCB0eXBlLCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QgKTtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGNvdW50OyBpICsrICkge1xuXG5cdFx0XHRnbC50ZXhJbWFnZTJEKCB0YXJnZXQgKyBpLCAwLCBnbC5SR0JBLCAxLCAxLCAwLCBnbC5SR0JBLCBnbC5VTlNJR05FRF9CWVRFLCBkYXRhICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGV4dHVyZTtcblxuXHR9XG5cblx0dmFyIGVtcHR5VGV4dHVyZXMgPSB7fTtcblx0ZW1wdHlUZXh0dXJlc1sgZ2wuVEVYVFVSRV8yRCBdID0gY3JlYXRlVGV4dHVyZSggZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV8yRCwgMSApO1xuXHRlbXB0eVRleHR1cmVzWyBnbC5URVhUVVJFX0NVQkVfTUFQIF0gPSBjcmVhdGVUZXh0dXJlKCBnbC5URVhUVVJFX0NVQkVfTUFQLCBnbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1gsIDYgKTtcblxuXHQvL1xuXG5cdGZ1bmN0aW9uIGluaXQoKSB7XG5cblx0XHRjb2xvckJ1ZmZlci5zZXRDbGVhciggMCwgMCwgMCwgMSApO1xuXHRcdGRlcHRoQnVmZmVyLnNldENsZWFyKCAxICk7XG5cdFx0c3RlbmNpbEJ1ZmZlci5zZXRDbGVhciggMCApO1xuXG5cdFx0ZW5hYmxlKCBnbC5ERVBUSF9URVNUICk7XG5cdFx0ZGVwdGhCdWZmZXIuc2V0RnVuYyggTGVzc0VxdWFsRGVwdGggKTtcblxuXHRcdHNldEZsaXBTaWRlZCggZmFsc2UgKTtcblx0XHRzZXRDdWxsRmFjZSggQ3VsbEZhY2VCYWNrICk7XG5cdFx0ZW5hYmxlKCBnbC5DVUxMX0ZBQ0UgKTtcblxuXHRcdGVuYWJsZSggZ2wuQkxFTkQgKTtcblx0XHRzZXRCbGVuZGluZyggTm9ybWFsQmxlbmRpbmcgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gaW5pdEF0dHJpYnV0ZXMoKSB7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBuZXdBdHRyaWJ1dGVzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdG5ld0F0dHJpYnV0ZXNbIGkgXSA9IDA7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGVuYWJsZUF0dHJpYnV0ZSggYXR0cmlidXRlICkge1xuXG5cdFx0bmV3QXR0cmlidXRlc1sgYXR0cmlidXRlIF0gPSAxO1xuXG5cdFx0aWYgKCBlbmFibGVkQXR0cmlidXRlc1sgYXR0cmlidXRlIF0gPT09IDAgKSB7XG5cblx0XHRcdGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KCBhdHRyaWJ1dGUgKTtcblx0XHRcdGVuYWJsZWRBdHRyaWJ1dGVzWyBhdHRyaWJ1dGUgXSA9IDE7XG5cblx0XHR9XG5cblx0XHRpZiAoIGF0dHJpYnV0ZURpdmlzb3JzWyBhdHRyaWJ1dGUgXSAhPT0gMCApIHtcblxuXHRcdFx0dmFyIGV4dGVuc2lvbiA9IGV4dGVuc2lvbnMuZ2V0KCAnQU5HTEVfaW5zdGFuY2VkX2FycmF5cycgKTtcblxuXHRcdFx0ZXh0ZW5zaW9uLnZlcnRleEF0dHJpYkRpdmlzb3JBTkdMRSggYXR0cmlidXRlLCAwICk7XG5cdFx0XHRhdHRyaWJ1dGVEaXZpc29yc1sgYXR0cmlidXRlIF0gPSAwO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBlbmFibGVBdHRyaWJ1dGVBbmREaXZpc29yKCBhdHRyaWJ1dGUsIG1lc2hQZXJBdHRyaWJ1dGUgKSB7XG5cblx0XHRuZXdBdHRyaWJ1dGVzWyBhdHRyaWJ1dGUgXSA9IDE7XG5cblx0XHRpZiAoIGVuYWJsZWRBdHRyaWJ1dGVzWyBhdHRyaWJ1dGUgXSA9PT0gMCApIHtcblxuXHRcdFx0Z2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoIGF0dHJpYnV0ZSApO1xuXHRcdFx0ZW5hYmxlZEF0dHJpYnV0ZXNbIGF0dHJpYnV0ZSBdID0gMTtcblxuXHRcdH1cblxuXHRcdGlmICggYXR0cmlidXRlRGl2aXNvcnNbIGF0dHJpYnV0ZSBdICE9PSBtZXNoUGVyQXR0cmlidXRlICkge1xuXG5cdFx0XHR2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9ucy5nZXQoICdBTkdMRV9pbnN0YW5jZWRfYXJyYXlzJyApO1xuXG5cdFx0XHRleHRlbnNpb24udmVydGV4QXR0cmliRGl2aXNvckFOR0xFKCBhdHRyaWJ1dGUsIG1lc2hQZXJBdHRyaWJ1dGUgKTtcblx0XHRcdGF0dHJpYnV0ZURpdmlzb3JzWyBhdHRyaWJ1dGUgXSA9IG1lc2hQZXJBdHRyaWJ1dGU7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGRpc2FibGVVbnVzZWRBdHRyaWJ1dGVzKCkge1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gZW5hYmxlZEF0dHJpYnV0ZXMubGVuZ3RoOyBpICE9PSBsOyArKyBpICkge1xuXG5cdFx0XHRpZiAoIGVuYWJsZWRBdHRyaWJ1dGVzWyBpIF0gIT09IG5ld0F0dHJpYnV0ZXNbIGkgXSApIHtcblxuXHRcdFx0XHRnbC5kaXNhYmxlVmVydGV4QXR0cmliQXJyYXkoIGkgKTtcblx0XHRcdFx0ZW5hYmxlZEF0dHJpYnV0ZXNbIGkgXSA9IDA7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gZW5hYmxlKCBpZCApIHtcblxuXHRcdGlmICggY2FwYWJpbGl0aWVzWyBpZCBdICE9PSB0cnVlICkge1xuXG5cdFx0XHRnbC5lbmFibGUoIGlkICk7XG5cdFx0XHRjYXBhYmlsaXRpZXNbIGlkIF0gPSB0cnVlO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBkaXNhYmxlKCBpZCApIHtcblxuXHRcdGlmICggY2FwYWJpbGl0aWVzWyBpZCBdICE9PSBmYWxzZSApIHtcblxuXHRcdFx0Z2wuZGlzYWJsZSggaWQgKTtcblx0XHRcdGNhcGFiaWxpdGllc1sgaWQgXSA9IGZhbHNlO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBnZXRDb21wcmVzc2VkVGV4dHVyZUZvcm1hdHMoKSB7XG5cblx0XHRpZiAoIGNvbXByZXNzZWRUZXh0dXJlRm9ybWF0cyA9PT0gbnVsbCApIHtcblxuXHRcdFx0Y29tcHJlc3NlZFRleHR1cmVGb3JtYXRzID0gW107XG5cblx0XHRcdGlmICggZXh0ZW5zaW9ucy5nZXQoICdXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfcHZydGMnICkgfHxcblx0XHRcdCAgICAgZXh0ZW5zaW9ucy5nZXQoICdXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfczN0YycgKSB8fFxuXHRcdFx0ICAgICBleHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9ldGMxJyApICkge1xuXG5cdFx0XHRcdHZhciBmb3JtYXRzID0gZ2wuZ2V0UGFyYW1ldGVyKCBnbC5DT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUUyApO1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGZvcm1hdHMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdFx0Y29tcHJlc3NlZFRleHR1cmVGb3JtYXRzLnB1c2goIGZvcm1hdHNbIGkgXSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvbXByZXNzZWRUZXh0dXJlRm9ybWF0cztcblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0QmxlbmRpbmcoIGJsZW5kaW5nLCBibGVuZEVxdWF0aW9uLCBibGVuZFNyYywgYmxlbmREc3QsIGJsZW5kRXF1YXRpb25BbHBoYSwgYmxlbmRTcmNBbHBoYSwgYmxlbmREc3RBbHBoYSwgcHJlbXVsdGlwbGllZEFscGhhICkge1xuXG5cdFx0aWYgKCBibGVuZGluZyAhPT0gTm9CbGVuZGluZyApIHtcblxuXHRcdFx0ZW5hYmxlKCBnbC5CTEVORCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0ZGlzYWJsZSggZ2wuQkxFTkQgKTtcblxuXHRcdH1cblxuXHRcdGlmICggYmxlbmRpbmcgIT09IGN1cnJlbnRCbGVuZGluZyB8fCBwcmVtdWx0aXBsaWVkQWxwaGEgIT09IGN1cnJlbnRQcmVtdWx0aXBsZWRBbHBoYSApIHtcblxuXHRcdFx0aWYgKCBibGVuZGluZyA9PT0gQWRkaXRpdmVCbGVuZGluZyApIHtcblxuXHRcdFx0XHRpZiAoIHByZW11bHRpcGxpZWRBbHBoYSApIHtcblxuXHRcdFx0XHRcdGdsLmJsZW5kRXF1YXRpb25TZXBhcmF0ZSggZ2wuRlVOQ19BREQsIGdsLkZVTkNfQUREICk7XG5cdFx0XHRcdFx0Z2wuYmxlbmRGdW5jU2VwYXJhdGUoIGdsLk9ORSwgZ2wuT05FLCBnbC5PTkUsIGdsLk9ORSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRnbC5ibGVuZEVxdWF0aW9uKCBnbC5GVU5DX0FERCApO1xuXHRcdFx0XHRcdGdsLmJsZW5kRnVuYyggZ2wuU1JDX0FMUEhBLCBnbC5PTkUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAoIGJsZW5kaW5nID09PSBTdWJ0cmFjdGl2ZUJsZW5kaW5nICkge1xuXG5cdFx0XHRcdGlmICggcHJlbXVsdGlwbGllZEFscGhhICkge1xuXG5cdFx0XHRcdFx0Z2wuYmxlbmRFcXVhdGlvblNlcGFyYXRlKCBnbC5GVU5DX0FERCwgZ2wuRlVOQ19BREQgKTtcblx0XHRcdFx0XHRnbC5ibGVuZEZ1bmNTZXBhcmF0ZSggZ2wuWkVSTywgZ2wuWkVSTywgZ2wuT05FX01JTlVTX1NSQ19DT0xPUiwgZ2wuT05FX01JTlVTX1NSQ19BTFBIQSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRnbC5ibGVuZEVxdWF0aW9uKCBnbC5GVU5DX0FERCApO1xuXHRcdFx0XHRcdGdsLmJsZW5kRnVuYyggZ2wuWkVSTywgZ2wuT05FX01JTlVTX1NSQ19DT0xPUiApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIGlmICggYmxlbmRpbmcgPT09IE11bHRpcGx5QmxlbmRpbmcgKSB7XG5cblx0XHRcdFx0aWYgKCBwcmVtdWx0aXBsaWVkQWxwaGEgKSB7XG5cblx0XHRcdFx0XHRnbC5ibGVuZEVxdWF0aW9uU2VwYXJhdGUoIGdsLkZVTkNfQURELCBnbC5GVU5DX0FERCApO1xuXHRcdFx0XHRcdGdsLmJsZW5kRnVuY1NlcGFyYXRlKCBnbC5aRVJPLCBnbC5TUkNfQ09MT1IsIGdsLlpFUk8sIGdsLlNSQ19BTFBIQSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRnbC5ibGVuZEVxdWF0aW9uKCBnbC5GVU5DX0FERCApO1xuXHRcdFx0XHRcdGdsLmJsZW5kRnVuYyggZ2wuWkVSTywgZ2wuU1JDX0NPTE9SICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGlmICggcHJlbXVsdGlwbGllZEFscGhhICkge1xuXG5cdFx0XHRcdFx0Z2wuYmxlbmRFcXVhdGlvblNlcGFyYXRlKCBnbC5GVU5DX0FERCwgZ2wuRlVOQ19BREQgKTtcblx0XHRcdFx0XHRnbC5ibGVuZEZ1bmNTZXBhcmF0ZSggZ2wuT05FLCBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBLCBnbC5PTkUsIGdsLk9ORV9NSU5VU19TUkNfQUxQSEEgKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Z2wuYmxlbmRFcXVhdGlvblNlcGFyYXRlKCBnbC5GVU5DX0FERCwgZ2wuRlVOQ19BREQgKTtcblx0XHRcdFx0XHRnbC5ibGVuZEZ1bmNTZXBhcmF0ZSggZ2wuU1JDX0FMUEhBLCBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBLCBnbC5PTkUsIGdsLk9ORV9NSU5VU19TUkNfQUxQSEEgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0Y3VycmVudEJsZW5kaW5nID0gYmxlbmRpbmc7XG5cdFx0XHRjdXJyZW50UHJlbXVsdGlwbGVkQWxwaGEgPSBwcmVtdWx0aXBsaWVkQWxwaGE7XG5cblx0XHR9XG5cblx0XHRpZiAoIGJsZW5kaW5nID09PSBDdXN0b21CbGVuZGluZyApIHtcblxuXHRcdFx0YmxlbmRFcXVhdGlvbkFscGhhID0gYmxlbmRFcXVhdGlvbkFscGhhIHx8IGJsZW5kRXF1YXRpb247XG5cdFx0XHRibGVuZFNyY0FscGhhID0gYmxlbmRTcmNBbHBoYSB8fCBibGVuZFNyYztcblx0XHRcdGJsZW5kRHN0QWxwaGEgPSBibGVuZERzdEFscGhhIHx8IGJsZW5kRHN0O1xuXG5cdFx0XHRpZiAoIGJsZW5kRXF1YXRpb24gIT09IGN1cnJlbnRCbGVuZEVxdWF0aW9uIHx8IGJsZW5kRXF1YXRpb25BbHBoYSAhPT0gY3VycmVudEJsZW5kRXF1YXRpb25BbHBoYSApIHtcblxuXHRcdFx0XHRnbC5ibGVuZEVxdWF0aW9uU2VwYXJhdGUoIHBhcmFtVGhyZWVUb0dMKCBibGVuZEVxdWF0aW9uICksIHBhcmFtVGhyZWVUb0dMKCBibGVuZEVxdWF0aW9uQWxwaGEgKSApO1xuXG5cdFx0XHRcdGN1cnJlbnRCbGVuZEVxdWF0aW9uID0gYmxlbmRFcXVhdGlvbjtcblx0XHRcdFx0Y3VycmVudEJsZW5kRXF1YXRpb25BbHBoYSA9IGJsZW5kRXF1YXRpb25BbHBoYTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGJsZW5kU3JjICE9PSBjdXJyZW50QmxlbmRTcmMgfHwgYmxlbmREc3QgIT09IGN1cnJlbnRCbGVuZERzdCB8fCBibGVuZFNyY0FscGhhICE9PSBjdXJyZW50QmxlbmRTcmNBbHBoYSB8fCBibGVuZERzdEFscGhhICE9PSBjdXJyZW50QmxlbmREc3RBbHBoYSApIHtcblxuXHRcdFx0XHRnbC5ibGVuZEZ1bmNTZXBhcmF0ZSggcGFyYW1UaHJlZVRvR0woIGJsZW5kU3JjICksIHBhcmFtVGhyZWVUb0dMKCBibGVuZERzdCApLCBwYXJhbVRocmVlVG9HTCggYmxlbmRTcmNBbHBoYSApLCBwYXJhbVRocmVlVG9HTCggYmxlbmREc3RBbHBoYSApICk7XG5cblx0XHRcdFx0Y3VycmVudEJsZW5kU3JjID0gYmxlbmRTcmM7XG5cdFx0XHRcdGN1cnJlbnRCbGVuZERzdCA9IGJsZW5kRHN0O1xuXHRcdFx0XHRjdXJyZW50QmxlbmRTcmNBbHBoYSA9IGJsZW5kU3JjQWxwaGE7XG5cdFx0XHRcdGN1cnJlbnRCbGVuZERzdEFscGhhID0gYmxlbmREc3RBbHBoYTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Y3VycmVudEJsZW5kRXF1YXRpb24gPSBudWxsO1xuXHRcdFx0Y3VycmVudEJsZW5kU3JjID0gbnVsbDtcblx0XHRcdGN1cnJlbnRCbGVuZERzdCA9IG51bGw7XG5cdFx0XHRjdXJyZW50QmxlbmRFcXVhdGlvbkFscGhhID0gbnVsbDtcblx0XHRcdGN1cnJlbnRCbGVuZFNyY0FscGhhID0gbnVsbDtcblx0XHRcdGN1cnJlbnRCbGVuZERzdEFscGhhID0gbnVsbDtcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0TWF0ZXJpYWwoIG1hdGVyaWFsICkge1xuXG5cdFx0bWF0ZXJpYWwuc2lkZSA9PT0gRG91YmxlU2lkZVxuXHRcdFx0PyBkaXNhYmxlKCBnbC5DVUxMX0ZBQ0UgKVxuXHRcdFx0OiBlbmFibGUoIGdsLkNVTExfRkFDRSApO1xuXG5cdFx0c2V0RmxpcFNpZGVkKCBtYXRlcmlhbC5zaWRlID09PSBCYWNrU2lkZSApO1xuXG5cdFx0bWF0ZXJpYWwudHJhbnNwYXJlbnQgPT09IHRydWVcblx0XHRcdD8gc2V0QmxlbmRpbmcoIG1hdGVyaWFsLmJsZW5kaW5nLCBtYXRlcmlhbC5ibGVuZEVxdWF0aW9uLCBtYXRlcmlhbC5ibGVuZFNyYywgbWF0ZXJpYWwuYmxlbmREc3QsIG1hdGVyaWFsLmJsZW5kRXF1YXRpb25BbHBoYSwgbWF0ZXJpYWwuYmxlbmRTcmNBbHBoYSwgbWF0ZXJpYWwuYmxlbmREc3RBbHBoYSwgbWF0ZXJpYWwucHJlbXVsdGlwbGllZEFscGhhIClcblx0XHRcdDogc2V0QmxlbmRpbmcoIE5vQmxlbmRpbmcgKTtcblxuXHRcdGRlcHRoQnVmZmVyLnNldEZ1bmMoIG1hdGVyaWFsLmRlcHRoRnVuYyApO1xuXHRcdGRlcHRoQnVmZmVyLnNldFRlc3QoIG1hdGVyaWFsLmRlcHRoVGVzdCApO1xuXHRcdGRlcHRoQnVmZmVyLnNldE1hc2soIG1hdGVyaWFsLmRlcHRoV3JpdGUgKTtcblx0XHRjb2xvckJ1ZmZlci5zZXRNYXNrKCBtYXRlcmlhbC5jb2xvcldyaXRlICk7XG5cblx0XHRzZXRQb2x5Z29uT2Zmc2V0KCBtYXRlcmlhbC5wb2x5Z29uT2Zmc2V0LCBtYXRlcmlhbC5wb2x5Z29uT2Zmc2V0RmFjdG9yLCBtYXRlcmlhbC5wb2x5Z29uT2Zmc2V0VW5pdHMgKTtcblxuXHR9XG5cblx0Ly9cblxuXHRmdW5jdGlvbiBzZXRGbGlwU2lkZWQoIGZsaXBTaWRlZCApIHtcblxuXHRcdGlmICggY3VycmVudEZsaXBTaWRlZCAhPT0gZmxpcFNpZGVkICkge1xuXG5cdFx0XHRpZiAoIGZsaXBTaWRlZCApIHtcblxuXHRcdFx0XHRnbC5mcm9udEZhY2UoIGdsLkNXICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Z2wuZnJvbnRGYWNlKCBnbC5DQ1cgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRjdXJyZW50RmxpcFNpZGVkID0gZmxpcFNpZGVkO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBzZXRDdWxsRmFjZSggY3VsbEZhY2UgKSB7XG5cblx0XHRpZiAoIGN1bGxGYWNlICE9PSBDdWxsRmFjZU5vbmUgKSB7XG5cblx0XHRcdGVuYWJsZSggZ2wuQ1VMTF9GQUNFICk7XG5cblx0XHRcdGlmICggY3VsbEZhY2UgIT09IGN1cnJlbnRDdWxsRmFjZSApIHtcblxuXHRcdFx0XHRpZiAoIGN1bGxGYWNlID09PSBDdWxsRmFjZUJhY2sgKSB7XG5cblx0XHRcdFx0XHRnbC5jdWxsRmFjZSggZ2wuQkFDSyApO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGN1bGxGYWNlID09PSBDdWxsRmFjZUZyb250ICkge1xuXG5cdFx0XHRcdFx0Z2wuY3VsbEZhY2UoIGdsLkZST05UICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGdsLmN1bGxGYWNlKCBnbC5GUk9OVF9BTkRfQkFDSyApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0ZGlzYWJsZSggZ2wuQ1VMTF9GQUNFICk7XG5cblx0XHR9XG5cblx0XHRjdXJyZW50Q3VsbEZhY2UgPSBjdWxsRmFjZTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0TGluZVdpZHRoKCB3aWR0aCApIHtcblxuXHRcdGlmICggd2lkdGggIT09IGN1cnJlbnRMaW5lV2lkdGggKSB7XG5cblx0XHRcdGlmICggbGluZVdpZHRoQXZhaWxhYmxlICkgZ2wubGluZVdpZHRoKCB3aWR0aCApO1xuXG5cdFx0XHRjdXJyZW50TGluZVdpZHRoID0gd2lkdGg7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHNldFBvbHlnb25PZmZzZXQoIHBvbHlnb25PZmZzZXQsIGZhY3RvciwgdW5pdHMgKSB7XG5cblx0XHRpZiAoIHBvbHlnb25PZmZzZXQgKSB7XG5cblx0XHRcdGVuYWJsZSggZ2wuUE9MWUdPTl9PRkZTRVRfRklMTCApO1xuXG5cdFx0XHRpZiAoIGN1cnJlbnRQb2x5Z29uT2Zmc2V0RmFjdG9yICE9PSBmYWN0b3IgfHwgY3VycmVudFBvbHlnb25PZmZzZXRVbml0cyAhPT0gdW5pdHMgKSB7XG5cblx0XHRcdFx0Z2wucG9seWdvbk9mZnNldCggZmFjdG9yLCB1bml0cyApO1xuXG5cdFx0XHRcdGN1cnJlbnRQb2x5Z29uT2Zmc2V0RmFjdG9yID0gZmFjdG9yO1xuXHRcdFx0XHRjdXJyZW50UG9seWdvbk9mZnNldFVuaXRzID0gdW5pdHM7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGRpc2FibGUoIGdsLlBPTFlHT05fT0ZGU0VUX0ZJTEwgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gZ2V0U2Npc3NvclRlc3QoKSB7XG5cblx0XHRyZXR1cm4gY3VycmVudFNjaXNzb3JUZXN0O1xuXG5cdH1cblxuXHRmdW5jdGlvbiBzZXRTY2lzc29yVGVzdCggc2Npc3NvclRlc3QgKSB7XG5cblx0XHRjdXJyZW50U2Npc3NvclRlc3QgPSBzY2lzc29yVGVzdDtcblxuXHRcdGlmICggc2Npc3NvclRlc3QgKSB7XG5cblx0XHRcdGVuYWJsZSggZ2wuU0NJU1NPUl9URVNUICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRkaXNhYmxlKCBnbC5TQ0lTU09SX1RFU1QgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gdGV4dHVyZVxuXG5cdGZ1bmN0aW9uIGFjdGl2ZVRleHR1cmUoIHdlYmdsU2xvdCApIHtcblxuXHRcdGlmICggd2ViZ2xTbG90ID09PSB1bmRlZmluZWQgKSB3ZWJnbFNsb3QgPSBnbC5URVhUVVJFMCArIG1heFRleHR1cmVzIC0gMTtcblxuXHRcdGlmICggY3VycmVudFRleHR1cmVTbG90ICE9PSB3ZWJnbFNsb3QgKSB7XG5cblx0XHRcdGdsLmFjdGl2ZVRleHR1cmUoIHdlYmdsU2xvdCApO1xuXHRcdFx0Y3VycmVudFRleHR1cmVTbG90ID0gd2ViZ2xTbG90O1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBiaW5kVGV4dHVyZSggd2ViZ2xUeXBlLCB3ZWJnbFRleHR1cmUgKSB7XG5cblx0XHRpZiAoIGN1cnJlbnRUZXh0dXJlU2xvdCA9PT0gbnVsbCApIHtcblxuXHRcdFx0YWN0aXZlVGV4dHVyZSgpO1xuXG5cdFx0fVxuXG5cdFx0dmFyIGJvdW5kVGV4dHVyZSA9IGN1cnJlbnRCb3VuZFRleHR1cmVzWyBjdXJyZW50VGV4dHVyZVNsb3QgXTtcblxuXHRcdGlmICggYm91bmRUZXh0dXJlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGJvdW5kVGV4dHVyZSA9IHsgdHlwZTogdW5kZWZpbmVkLCB0ZXh0dXJlOiB1bmRlZmluZWQgfTtcblx0XHRcdGN1cnJlbnRCb3VuZFRleHR1cmVzWyBjdXJyZW50VGV4dHVyZVNsb3QgXSA9IGJvdW5kVGV4dHVyZTtcblxuXHRcdH1cblxuXHRcdGlmICggYm91bmRUZXh0dXJlLnR5cGUgIT09IHdlYmdsVHlwZSB8fCBib3VuZFRleHR1cmUudGV4dHVyZSAhPT0gd2ViZ2xUZXh0dXJlICkge1xuXG5cdFx0XHRnbC5iaW5kVGV4dHVyZSggd2ViZ2xUeXBlLCB3ZWJnbFRleHR1cmUgfHwgZW1wdHlUZXh0dXJlc1sgd2ViZ2xUeXBlIF0gKTtcblxuXHRcdFx0Ym91bmRUZXh0dXJlLnR5cGUgPSB3ZWJnbFR5cGU7XG5cdFx0XHRib3VuZFRleHR1cmUudGV4dHVyZSA9IHdlYmdsVGV4dHVyZTtcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gY29tcHJlc3NlZFRleEltYWdlMkQoKSB7XG5cblx0XHR0cnkge1xuXG5cdFx0XHRnbC5jb21wcmVzc2VkVGV4SW1hZ2UyRC5hcHBseSggZ2wsIGFyZ3VtZW50cyApO1xuXG5cdFx0fSBjYXRjaCAoIGVycm9yICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCBlcnJvciApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiB0ZXhJbWFnZTJEKCkge1xuXG5cdFx0dHJ5IHtcblxuXHRcdFx0Z2wudGV4SW1hZ2UyRC5hcHBseSggZ2wsIGFyZ3VtZW50cyApO1xuXG5cdFx0fSBjYXRjaCAoIGVycm9yICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCBlcnJvciApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvL1xuXG5cdGZ1bmN0aW9uIHNjaXNzb3IoIHNjaXNzb3IgKSB7XG5cblx0XHRpZiAoIGN1cnJlbnRTY2lzc29yLmVxdWFscyggc2Npc3NvciApID09PSBmYWxzZSApIHtcblxuXHRcdFx0Z2wuc2Npc3Nvciggc2Npc3Nvci54LCBzY2lzc29yLnksIHNjaXNzb3Iueiwgc2Npc3Nvci53ICk7XG5cdFx0XHRjdXJyZW50U2Npc3Nvci5jb3B5KCBzY2lzc29yICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHZpZXdwb3J0KCB2aWV3cG9ydCApIHtcblxuXHRcdGlmICggY3VycmVudFZpZXdwb3J0LmVxdWFscyggdmlld3BvcnQgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGdsLnZpZXdwb3J0KCB2aWV3cG9ydC54LCB2aWV3cG9ydC55LCB2aWV3cG9ydC56LCB2aWV3cG9ydC53ICk7XG5cdFx0XHRjdXJyZW50Vmlld3BvcnQuY29weSggdmlld3BvcnQgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Ly9cblxuXHRmdW5jdGlvbiByZXNldCgpIHtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGVuYWJsZWRBdHRyaWJ1dGVzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0aWYgKCBlbmFibGVkQXR0cmlidXRlc1sgaSBdID09PSAxICkge1xuXG5cdFx0XHRcdGdsLmRpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheSggaSApO1xuXHRcdFx0XHRlbmFibGVkQXR0cmlidXRlc1sgaSBdID0gMDtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Y2FwYWJpbGl0aWVzID0ge307XG5cblx0XHRjb21wcmVzc2VkVGV4dHVyZUZvcm1hdHMgPSBudWxsO1xuXG5cdFx0Y3VycmVudFRleHR1cmVTbG90ID0gbnVsbDtcblx0XHRjdXJyZW50Qm91bmRUZXh0dXJlcyA9IHt9O1xuXG5cdFx0Y3VycmVudEJsZW5kaW5nID0gbnVsbDtcblxuXHRcdGN1cnJlbnRGbGlwU2lkZWQgPSBudWxsO1xuXHRcdGN1cnJlbnRDdWxsRmFjZSA9IG51bGw7XG5cblx0XHRjb2xvckJ1ZmZlci5yZXNldCgpO1xuXHRcdGRlcHRoQnVmZmVyLnJlc2V0KCk7XG5cdFx0c3RlbmNpbEJ1ZmZlci5yZXNldCgpO1xuXG5cdH1cblxuXHRyZXR1cm4ge1xuXG5cdFx0YnVmZmVyczoge1xuXHRcdFx0Y29sb3I6IGNvbG9yQnVmZmVyLFxuXHRcdFx0ZGVwdGg6IGRlcHRoQnVmZmVyLFxuXHRcdFx0c3RlbmNpbDogc3RlbmNpbEJ1ZmZlclxuXHRcdH0sXG5cblx0XHRpbml0OiBpbml0LFxuXHRcdGluaXRBdHRyaWJ1dGVzOiBpbml0QXR0cmlidXRlcyxcblx0XHRlbmFibGVBdHRyaWJ1dGU6IGVuYWJsZUF0dHJpYnV0ZSxcblx0XHRlbmFibGVBdHRyaWJ1dGVBbmREaXZpc29yOiBlbmFibGVBdHRyaWJ1dGVBbmREaXZpc29yLFxuXHRcdGRpc2FibGVVbnVzZWRBdHRyaWJ1dGVzOiBkaXNhYmxlVW51c2VkQXR0cmlidXRlcyxcblx0XHRlbmFibGU6IGVuYWJsZSxcblx0XHRkaXNhYmxlOiBkaXNhYmxlLFxuXHRcdGdldENvbXByZXNzZWRUZXh0dXJlRm9ybWF0czogZ2V0Q29tcHJlc3NlZFRleHR1cmVGb3JtYXRzLFxuXG5cdFx0c2V0QmxlbmRpbmc6IHNldEJsZW5kaW5nLFxuXHRcdHNldE1hdGVyaWFsOiBzZXRNYXRlcmlhbCxcblxuXHRcdHNldEZsaXBTaWRlZDogc2V0RmxpcFNpZGVkLFxuXHRcdHNldEN1bGxGYWNlOiBzZXRDdWxsRmFjZSxcblxuXHRcdHNldExpbmVXaWR0aDogc2V0TGluZVdpZHRoLFxuXHRcdHNldFBvbHlnb25PZmZzZXQ6IHNldFBvbHlnb25PZmZzZXQsXG5cblx0XHRnZXRTY2lzc29yVGVzdDogZ2V0U2Npc3NvclRlc3QsXG5cdFx0c2V0U2Npc3NvclRlc3Q6IHNldFNjaXNzb3JUZXN0LFxuXG5cdFx0YWN0aXZlVGV4dHVyZTogYWN0aXZlVGV4dHVyZSxcblx0XHRiaW5kVGV4dHVyZTogYmluZFRleHR1cmUsXG5cdFx0Y29tcHJlc3NlZFRleEltYWdlMkQ6IGNvbXByZXNzZWRUZXhJbWFnZTJELFxuXHRcdHRleEltYWdlMkQ6IHRleEltYWdlMkQsXG5cblx0XHRzY2lzc29yOiBzY2lzc29yLFxuXHRcdHZpZXdwb3J0OiB2aWV3cG9ydCxcblxuXHRcdHJlc2V0OiByZXNldFxuXG5cdH07XG5cbn1cblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFdlYkdMQ2FwYWJpbGl0aWVzKCBnbCwgZXh0ZW5zaW9ucywgcGFyYW1ldGVycyApIHtcblxuXHR2YXIgbWF4QW5pc290cm9weTtcblxuXHRmdW5jdGlvbiBnZXRNYXhBbmlzb3Ryb3B5KCkge1xuXG5cdFx0aWYgKCBtYXhBbmlzb3Ryb3B5ICE9PSB1bmRlZmluZWQgKSByZXR1cm4gbWF4QW5pc290cm9weTtcblxuXHRcdHZhciBleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ0VYVF90ZXh0dXJlX2ZpbHRlcl9hbmlzb3Ryb3BpYycgKTtcblxuXHRcdGlmICggZXh0ZW5zaW9uICE9PSBudWxsICkge1xuXG5cdFx0XHRtYXhBbmlzb3Ryb3B5ID0gZ2wuZ2V0UGFyYW1ldGVyKCBleHRlbnNpb24uTUFYX1RFWFRVUkVfTUFYX0FOSVNPVFJPUFlfRVhUICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRtYXhBbmlzb3Ryb3B5ID0gMDtcblxuXHRcdH1cblxuXHRcdHJldHVybiBtYXhBbmlzb3Ryb3B5O1xuXG5cdH1cblxuXHRmdW5jdGlvbiBnZXRNYXhQcmVjaXNpb24oIHByZWNpc2lvbiApIHtcblxuXHRcdGlmICggcHJlY2lzaW9uID09PSAnaGlnaHAnICkge1xuXG5cdFx0XHRpZiAoIGdsLmdldFNoYWRlclByZWNpc2lvbkZvcm1hdCggZ2wuVkVSVEVYX1NIQURFUiwgZ2wuSElHSF9GTE9BVCApLnByZWNpc2lvbiA+IDAgJiZcblx0XHRcdCAgICAgZ2wuZ2V0U2hhZGVyUHJlY2lzaW9uRm9ybWF0KCBnbC5GUkFHTUVOVF9TSEFERVIsIGdsLkhJR0hfRkxPQVQgKS5wcmVjaXNpb24gPiAwICkge1xuXG5cdFx0XHRcdHJldHVybiAnaGlnaHAnO1xuXG5cdFx0XHR9XG5cblx0XHRcdHByZWNpc2lvbiA9ICdtZWRpdW1wJztcblxuXHRcdH1cblxuXHRcdGlmICggcHJlY2lzaW9uID09PSAnbWVkaXVtcCcgKSB7XG5cblx0XHRcdGlmICggZ2wuZ2V0U2hhZGVyUHJlY2lzaW9uRm9ybWF0KCBnbC5WRVJURVhfU0hBREVSLCBnbC5NRURJVU1fRkxPQVQgKS5wcmVjaXNpb24gPiAwICYmXG5cdFx0XHQgICAgIGdsLmdldFNoYWRlclByZWNpc2lvbkZvcm1hdCggZ2wuRlJBR01FTlRfU0hBREVSLCBnbC5NRURJVU1fRkxPQVQgKS5wcmVjaXNpb24gPiAwICkge1xuXG5cdFx0XHRcdHJldHVybiAnbWVkaXVtcCc7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiAnbG93cCc7XG5cblx0fVxuXG5cdHZhciBwcmVjaXNpb24gPSBwYXJhbWV0ZXJzLnByZWNpc2lvbiAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5wcmVjaXNpb24gOiAnaGlnaHAnO1xuXHR2YXIgbWF4UHJlY2lzaW9uID0gZ2V0TWF4UHJlY2lzaW9uKCBwcmVjaXNpb24gKTtcblxuXHRpZiAoIG1heFByZWNpc2lvbiAhPT0gcHJlY2lzaW9uICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjonLCBwcmVjaXNpb24sICdub3Qgc3VwcG9ydGVkLCB1c2luZycsIG1heFByZWNpc2lvbiwgJ2luc3RlYWQuJyApO1xuXHRcdHByZWNpc2lvbiA9IG1heFByZWNpc2lvbjtcblxuXHR9XG5cblx0dmFyIGxvZ2FyaXRobWljRGVwdGhCdWZmZXIgPSBwYXJhbWV0ZXJzLmxvZ2FyaXRobWljRGVwdGhCdWZmZXIgPT09IHRydWUgJiYgISEgZXh0ZW5zaW9ucy5nZXQoICdFWFRfZnJhZ19kZXB0aCcgKTtcblxuXHR2YXIgbWF4VGV4dHVyZXMgPSBnbC5nZXRQYXJhbWV0ZXIoIGdsLk1BWF9URVhUVVJFX0lNQUdFX1VOSVRTICk7XG5cdHZhciBtYXhWZXJ0ZXhUZXh0dXJlcyA9IGdsLmdldFBhcmFtZXRlciggZ2wuTUFYX1ZFUlRFWF9URVhUVVJFX0lNQUdFX1VOSVRTICk7XG5cdHZhciBtYXhUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlciggZ2wuTUFYX1RFWFRVUkVfU0laRSApO1xuXHR2YXIgbWF4Q3ViZW1hcFNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoIGdsLk1BWF9DVUJFX01BUF9URVhUVVJFX1NJWkUgKTtcblxuXHR2YXIgbWF4QXR0cmlidXRlcyA9IGdsLmdldFBhcmFtZXRlciggZ2wuTUFYX1ZFUlRFWF9BVFRSSUJTICk7XG5cdHZhciBtYXhWZXJ0ZXhVbmlmb3JtcyA9IGdsLmdldFBhcmFtZXRlciggZ2wuTUFYX1ZFUlRFWF9VTklGT1JNX1ZFQ1RPUlMgKTtcblx0dmFyIG1heFZhcnlpbmdzID0gZ2wuZ2V0UGFyYW1ldGVyKCBnbC5NQVhfVkFSWUlOR19WRUNUT1JTICk7XG5cdHZhciBtYXhGcmFnbWVudFVuaWZvcm1zID0gZ2wuZ2V0UGFyYW1ldGVyKCBnbC5NQVhfRlJBR01FTlRfVU5JRk9STV9WRUNUT1JTICk7XG5cblx0dmFyIHZlcnRleFRleHR1cmVzID0gbWF4VmVydGV4VGV4dHVyZXMgPiAwO1xuXHR2YXIgZmxvYXRGcmFnbWVudFRleHR1cmVzID0gISEgZXh0ZW5zaW9ucy5nZXQoICdPRVNfdGV4dHVyZV9mbG9hdCcgKTtcblx0dmFyIGZsb2F0VmVydGV4VGV4dHVyZXMgPSB2ZXJ0ZXhUZXh0dXJlcyAmJiBmbG9hdEZyYWdtZW50VGV4dHVyZXM7XG5cblx0cmV0dXJuIHtcblxuXHRcdGdldE1heEFuaXNvdHJvcHk6IGdldE1heEFuaXNvdHJvcHksXG5cdFx0Z2V0TWF4UHJlY2lzaW9uOiBnZXRNYXhQcmVjaXNpb24sXG5cblx0XHRwcmVjaXNpb246IHByZWNpc2lvbixcblx0XHRsb2dhcml0aG1pY0RlcHRoQnVmZmVyOiBsb2dhcml0aG1pY0RlcHRoQnVmZmVyLFxuXG5cdFx0bWF4VGV4dHVyZXM6IG1heFRleHR1cmVzLFxuXHRcdG1heFZlcnRleFRleHR1cmVzOiBtYXhWZXJ0ZXhUZXh0dXJlcyxcblx0XHRtYXhUZXh0dXJlU2l6ZTogbWF4VGV4dHVyZVNpemUsXG5cdFx0bWF4Q3ViZW1hcFNpemU6IG1heEN1YmVtYXBTaXplLFxuXG5cdFx0bWF4QXR0cmlidXRlczogbWF4QXR0cmlidXRlcyxcblx0XHRtYXhWZXJ0ZXhVbmlmb3JtczogbWF4VmVydGV4VW5pZm9ybXMsXG5cdFx0bWF4VmFyeWluZ3M6IG1heFZhcnlpbmdzLFxuXHRcdG1heEZyYWdtZW50VW5pZm9ybXM6IG1heEZyYWdtZW50VW5pZm9ybXMsXG5cblx0XHR2ZXJ0ZXhUZXh0dXJlczogdmVydGV4VGV4dHVyZXMsXG5cdFx0ZmxvYXRGcmFnbWVudFRleHR1cmVzOiBmbG9hdEZyYWdtZW50VGV4dHVyZXMsXG5cdFx0ZmxvYXRWZXJ0ZXhUZXh0dXJlczogZmxvYXRWZXJ0ZXhUZXh0dXJlc1xuXG5cdH07XG5cbn1cblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFdlYkdMRXh0ZW5zaW9ucyggZ2wgKSB7XG5cblx0dmFyIGV4dGVuc2lvbnMgPSB7fTtcblxuXHRyZXR1cm4ge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoIG5hbWUgKSB7XG5cblx0XHRcdGlmICggZXh0ZW5zaW9uc1sgbmFtZSBdICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0cmV0dXJuIGV4dGVuc2lvbnNbIG5hbWUgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZXh0ZW5zaW9uO1xuXG5cdFx0XHRzd2l0Y2ggKCBuYW1lICkge1xuXG5cdFx0XHRcdGNhc2UgJ1dFQkdMX2RlcHRoX3RleHR1cmUnOlxuXHRcdFx0XHRcdGV4dGVuc2lvbiA9IGdsLmdldEV4dGVuc2lvbiggJ1dFQkdMX2RlcHRoX3RleHR1cmUnICkgfHwgZ2wuZ2V0RXh0ZW5zaW9uKCAnTU9aX1dFQkdMX2RlcHRoX3RleHR1cmUnICkgfHwgZ2wuZ2V0RXh0ZW5zaW9uKCAnV0VCS0lUX1dFQkdMX2RlcHRoX3RleHR1cmUnICk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljJzpcblx0XHRcdFx0XHRleHRlbnNpb24gPSBnbC5nZXRFeHRlbnNpb24oICdFWFRfdGV4dHVyZV9maWx0ZXJfYW5pc290cm9waWMnICkgfHwgZ2wuZ2V0RXh0ZW5zaW9uKCAnTU9aX0VYVF90ZXh0dXJlX2ZpbHRlcl9hbmlzb3Ryb3BpYycgKSB8fCBnbC5nZXRFeHRlbnNpb24oICdXRUJLSVRfRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljJyApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9zM3RjJzpcblx0XHRcdFx0XHRleHRlbnNpb24gPSBnbC5nZXRFeHRlbnNpb24oICdXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfczN0YycgKSB8fCBnbC5nZXRFeHRlbnNpb24oICdNT1pfV0VCR0xfY29tcHJlc3NlZF90ZXh0dXJlX3MzdGMnICkgfHwgZ2wuZ2V0RXh0ZW5zaW9uKCAnV0VCS0lUX1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9zM3RjJyApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9wdnJ0Yyc6XG5cdFx0XHRcdFx0ZXh0ZW5zaW9uID0gZ2wuZ2V0RXh0ZW5zaW9uKCAnV0VCR0xfY29tcHJlc3NlZF90ZXh0dXJlX3B2cnRjJyApIHx8IGdsLmdldEV4dGVuc2lvbiggJ1dFQktJVF9XRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfcHZydGMnICk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnV0VCR0xfY29tcHJlc3NlZF90ZXh0dXJlX2V0YzEnOlxuXHRcdFx0XHRcdGV4dGVuc2lvbiA9IGdsLmdldEV4dGVuc2lvbiggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9ldGMxJyApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0ZXh0ZW5zaW9uID0gZ2wuZ2V0RXh0ZW5zaW9uKCBuYW1lICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBleHRlbnNpb24gPT09IG51bGwgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogJyArIG5hbWUgKyAnIGV4dGVuc2lvbiBub3Qgc3VwcG9ydGVkLicgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRleHRlbnNpb25zWyBuYW1lIF0gPSBleHRlbnNpb247XG5cblx0XHRcdHJldHVybiBleHRlbnNpb247XG5cblx0XHR9XG5cblx0fTtcblxufVxuXG4vKipcbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBXZWJHTENsaXBwaW5nKCkge1xuXG5cdHZhciBzY29wZSA9IHRoaXMsXG5cblx0XHRnbG9iYWxTdGF0ZSA9IG51bGwsXG5cdFx0bnVtR2xvYmFsUGxhbmVzID0gMCxcblx0XHRsb2NhbENsaXBwaW5nRW5hYmxlZCA9IGZhbHNlLFxuXHRcdHJlbmRlcmluZ1NoYWRvd3MgPSBmYWxzZSxcblxuXHRcdHBsYW5lID0gbmV3IFBsYW5lKCksXG5cdFx0dmlld05vcm1hbE1hdHJpeCA9IG5ldyBNYXRyaXgzKCksXG5cblx0XHR1bmlmb3JtID0geyB2YWx1ZTogbnVsbCwgbmVlZHNVcGRhdGU6IGZhbHNlIH07XG5cblx0dGhpcy51bmlmb3JtID0gdW5pZm9ybTtcblx0dGhpcy5udW1QbGFuZXMgPSAwO1xuXHR0aGlzLm51bUludGVyc2VjdGlvbiA9IDA7XG5cblx0dGhpcy5pbml0ID0gZnVuY3Rpb24oIHBsYW5lcywgZW5hYmxlTG9jYWxDbGlwcGluZywgY2FtZXJhICkge1xuXG5cdFx0dmFyIGVuYWJsZWQgPVxuXHRcdFx0cGxhbmVzLmxlbmd0aCAhPT0gMCB8fFxuXHRcdFx0ZW5hYmxlTG9jYWxDbGlwcGluZyB8fFxuXHRcdFx0Ly8gZW5hYmxlIHN0YXRlIG9mIHByZXZpb3VzIGZyYW1lIC0gdGhlIGNsaXBwaW5nIGNvZGUgaGFzIHRvXG5cdFx0XHQvLyBydW4gYW5vdGhlciBmcmFtZSBpbiBvcmRlciB0byByZXNldCB0aGUgc3RhdGU6XG5cdFx0XHRudW1HbG9iYWxQbGFuZXMgIT09IDAgfHxcblx0XHRcdGxvY2FsQ2xpcHBpbmdFbmFibGVkO1xuXG5cdFx0bG9jYWxDbGlwcGluZ0VuYWJsZWQgPSBlbmFibGVMb2NhbENsaXBwaW5nO1xuXG5cdFx0Z2xvYmFsU3RhdGUgPSBwcm9qZWN0UGxhbmVzKCBwbGFuZXMsIGNhbWVyYSwgMCApO1xuXHRcdG51bUdsb2JhbFBsYW5lcyA9IHBsYW5lcy5sZW5ndGg7XG5cblx0XHRyZXR1cm4gZW5hYmxlZDtcblxuXHR9O1xuXG5cdHRoaXMuYmVnaW5TaGFkb3dzID0gZnVuY3Rpb24oKSB7XG5cblx0XHRyZW5kZXJpbmdTaGFkb3dzID0gdHJ1ZTtcblx0XHRwcm9qZWN0UGxhbmVzKCBudWxsICk7XG5cblx0fTtcblxuXHR0aGlzLmVuZFNoYWRvd3MgPSBmdW5jdGlvbigpIHtcblxuXHRcdHJlbmRlcmluZ1NoYWRvd3MgPSBmYWxzZTtcblx0XHRyZXNldEdsb2JhbFN0YXRlKCk7XG5cblx0fTtcblxuXHR0aGlzLnNldFN0YXRlID0gZnVuY3Rpb24oIHBsYW5lcywgY2xpcEludGVyc2VjdGlvbiwgY2xpcFNoYWRvd3MsIGNhbWVyYSwgY2FjaGUsIGZyb21DYWNoZSApIHtcblxuXHRcdGlmICggISBsb2NhbENsaXBwaW5nRW5hYmxlZCB8fFxuXHRcdFx0XHRwbGFuZXMgPT09IG51bGwgfHwgcGxhbmVzLmxlbmd0aCA9PT0gMCB8fFxuXHRcdFx0XHRyZW5kZXJpbmdTaGFkb3dzICYmICEgY2xpcFNoYWRvd3MgKSB7XG5cdFx0XHQvLyB0aGVyZSdzIG5vIGxvY2FsIGNsaXBwaW5nXG5cblx0XHRcdGlmICggcmVuZGVyaW5nU2hhZG93cyApIHtcblx0XHRcdFx0Ly8gdGhlcmUncyBubyBnbG9iYWwgY2xpcHBpbmdcblxuXHRcdFx0XHRwcm9qZWN0UGxhbmVzKCBudWxsICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0cmVzZXRHbG9iYWxTdGF0ZSgpO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dmFyIG5HbG9iYWwgPSByZW5kZXJpbmdTaGFkb3dzID8gMCA6IG51bUdsb2JhbFBsYW5lcyxcblx0XHRcdFx0bEdsb2JhbCA9IG5HbG9iYWwgKiA0LFxuXG5cdFx0XHRcdGRzdEFycmF5ID0gY2FjaGUuY2xpcHBpbmdTdGF0ZSB8fCBudWxsO1xuXG5cdFx0XHR1bmlmb3JtLnZhbHVlID0gZHN0QXJyYXk7IC8vIGVuc3VyZSB1bmlxdWUgc3RhdGVcblxuXHRcdFx0ZHN0QXJyYXkgPSBwcm9qZWN0UGxhbmVzKCBwbGFuZXMsIGNhbWVyYSwgbEdsb2JhbCwgZnJvbUNhY2hlICk7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gbEdsb2JhbDsgKysgaSApIHtcblxuXHRcdFx0XHRkc3RBcnJheVsgaSBdID0gZ2xvYmFsU3RhdGVbIGkgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRjYWNoZS5jbGlwcGluZ1N0YXRlID0gZHN0QXJyYXk7XG5cdFx0XHR0aGlzLm51bUludGVyc2VjdGlvbiA9IGNsaXBJbnRlcnNlY3Rpb24gPyB0aGlzLm51bVBsYW5lcyA6IDA7XG5cdFx0XHR0aGlzLm51bVBsYW5lcyArPSBuR2xvYmFsO1xuXG5cdFx0fVxuXG5cblx0fTtcblxuXHRmdW5jdGlvbiByZXNldEdsb2JhbFN0YXRlKCkge1xuXG5cdFx0aWYgKCB1bmlmb3JtLnZhbHVlICE9PSBnbG9iYWxTdGF0ZSApIHtcblxuXHRcdFx0dW5pZm9ybS52YWx1ZSA9IGdsb2JhbFN0YXRlO1xuXHRcdFx0dW5pZm9ybS5uZWVkc1VwZGF0ZSA9IG51bUdsb2JhbFBsYW5lcyA+IDA7XG5cblx0XHR9XG5cblx0XHRzY29wZS5udW1QbGFuZXMgPSBudW1HbG9iYWxQbGFuZXM7XG5cdFx0c2NvcGUubnVtSW50ZXJzZWN0aW9uID0gMDtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcHJvamVjdFBsYW5lcyggcGxhbmVzLCBjYW1lcmEsIGRzdE9mZnNldCwgc2tpcFRyYW5zZm9ybSApIHtcblxuXHRcdHZhciBuUGxhbmVzID0gcGxhbmVzICE9PSBudWxsID8gcGxhbmVzLmxlbmd0aCA6IDAsXG5cdFx0XHRkc3RBcnJheSA9IG51bGw7XG5cblx0XHRpZiAoIG5QbGFuZXMgIT09IDAgKSB7XG5cblx0XHRcdGRzdEFycmF5ID0gdW5pZm9ybS52YWx1ZTtcblxuXHRcdFx0aWYgKCBza2lwVHJhbnNmb3JtICE9PSB0cnVlIHx8IGRzdEFycmF5ID09PSBudWxsICkge1xuXG5cdFx0XHRcdHZhciBmbGF0U2l6ZSA9IGRzdE9mZnNldCArIG5QbGFuZXMgKiA0LFxuXHRcdFx0XHRcdHZpZXdNYXRyaXggPSBjYW1lcmEubWF0cml4V29ybGRJbnZlcnNlO1xuXG5cdFx0XHRcdHZpZXdOb3JtYWxNYXRyaXguZ2V0Tm9ybWFsTWF0cml4KCB2aWV3TWF0cml4ICk7XG5cblx0XHRcdFx0aWYgKCBkc3RBcnJheSA9PT0gbnVsbCB8fCBkc3RBcnJheS5sZW5ndGggPCBmbGF0U2l6ZSApIHtcblxuXHRcdFx0XHRcdGRzdEFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSggZmxhdFNpemUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpNCA9IGRzdE9mZnNldDtcblx0XHRcdFx0XHRcdFx0XHRcdGkgIT09IG5QbGFuZXM7ICsrIGksIGk0ICs9IDQgKSB7XG5cblx0XHRcdFx0XHRwbGFuZS5jb3B5KCBwbGFuZXNbIGkgXSApLlxuXHRcdFx0XHRcdFx0XHRhcHBseU1hdHJpeDQoIHZpZXdNYXRyaXgsIHZpZXdOb3JtYWxNYXRyaXggKTtcblxuXHRcdFx0XHRcdHBsYW5lLm5vcm1hbC50b0FycmF5KCBkc3RBcnJheSwgaTQgKTtcblx0XHRcdFx0XHRkc3RBcnJheVsgaTQgKyAzIF0gPSBwbGFuZS5jb25zdGFudDtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0dW5pZm9ybS52YWx1ZSA9IGRzdEFycmF5O1xuXHRcdFx0dW5pZm9ybS5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHR9XG5cblx0XHRzY29wZS5udW1QbGFuZXMgPSBuUGxhbmVzO1xuXHRcdFxuXHRcdHJldHVybiBkc3RBcnJheTtcblxuXHR9XG5cbn1cblxuLy8gaW1wb3J0IHsgU3BoZXJlIH0gZnJvbSAnLi4vbWF0aC9TcGhlcmUnO1xuLyoqXG4gKiBAYXV0aG9yIHN1cGVyZWdnYmVydCAvIGh0dHA6Ly93d3cucGF1bGJydW50LmNvLnVrL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIHN6aW1layAvIGh0dHBzOi8vZ2l0aHViLmNvbS9zemltZWsvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gV2ViR0xSZW5kZXJlciggcGFyYW1ldGVycyApIHtcblxuXHRjb25zb2xlLmxvZyggJ1RIUkVFLldlYkdMUmVuZGVyZXInLCBSRVZJU0lPTiApO1xuXG5cdHBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzIHx8IHt9O1xuXG5cdHZhciBfY2FudmFzID0gcGFyYW1ldGVycy5jYW52YXMgIT09IHVuZGVmaW5lZCA/IHBhcmFtZXRlcnMuY2FudmFzIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCcsICdjYW52YXMnICksXG5cdFx0X2NvbnRleHQgPSBwYXJhbWV0ZXJzLmNvbnRleHQgIT09IHVuZGVmaW5lZCA/IHBhcmFtZXRlcnMuY29udGV4dCA6IG51bGwsXG5cblx0XHRfYWxwaGEgPSBwYXJhbWV0ZXJzLmFscGhhICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzLmFscGhhIDogZmFsc2UsXG5cdFx0X2RlcHRoID0gcGFyYW1ldGVycy5kZXB0aCAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5kZXB0aCA6IHRydWUsXG5cdFx0X3N0ZW5jaWwgPSBwYXJhbWV0ZXJzLnN0ZW5jaWwgIT09IHVuZGVmaW5lZCA/IHBhcmFtZXRlcnMuc3RlbmNpbCA6IHRydWUsXG5cdFx0X2FudGlhbGlhcyA9IHBhcmFtZXRlcnMuYW50aWFsaWFzICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzLmFudGlhbGlhcyA6IGZhbHNlLFxuXHRcdF9wcmVtdWx0aXBsaWVkQWxwaGEgPSBwYXJhbWV0ZXJzLnByZW11bHRpcGxpZWRBbHBoYSAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5wcmVtdWx0aXBsaWVkQWxwaGEgOiB0cnVlLFxuXHRcdF9wcmVzZXJ2ZURyYXdpbmdCdWZmZXIgPSBwYXJhbWV0ZXJzLnByZXNlcnZlRHJhd2luZ0J1ZmZlciAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVycy5wcmVzZXJ2ZURyYXdpbmdCdWZmZXIgOiBmYWxzZTtcblxuXHR2YXIgbGlnaHRzID0gW107XG5cblx0dmFyIGN1cnJlbnRSZW5kZXJMaXN0ID0gbnVsbDtcblxuXHR2YXIgbW9ycGhJbmZsdWVuY2VzID0gbmV3IEZsb2F0MzJBcnJheSggOCApO1xuXG5cdHZhciBzcHJpdGVzID0gW107XG5cdHZhciBsZW5zRmxhcmVzID0gW107XG5cblx0Ly8gcHVibGljIHByb3BlcnRpZXNcblxuXHR0aGlzLmRvbUVsZW1lbnQgPSBfY2FudmFzO1xuXHR0aGlzLmNvbnRleHQgPSBudWxsO1xuXG5cdC8vIGNsZWFyaW5nXG5cblx0dGhpcy5hdXRvQ2xlYXIgPSB0cnVlO1xuXHR0aGlzLmF1dG9DbGVhckNvbG9yID0gdHJ1ZTtcblx0dGhpcy5hdXRvQ2xlYXJEZXB0aCA9IHRydWU7XG5cdHRoaXMuYXV0b0NsZWFyU3RlbmNpbCA9IHRydWU7XG5cblx0Ly8gc2NlbmUgZ3JhcGhcblxuXHR0aGlzLnNvcnRPYmplY3RzID0gdHJ1ZTtcblxuXHQvLyB1c2VyLWRlZmluZWQgY2xpcHBpbmdcblxuXHR0aGlzLmNsaXBwaW5nUGxhbmVzID0gW107XG5cdHRoaXMubG9jYWxDbGlwcGluZ0VuYWJsZWQgPSBmYWxzZTtcblxuXHQvLyBwaHlzaWNhbGx5IGJhc2VkIHNoYWRpbmdcblxuXHR0aGlzLmdhbW1hRmFjdG9yID0gMi4wO1x0Ly8gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdHRoaXMuZ2FtbWFJbnB1dCA9IGZhbHNlO1xuXHR0aGlzLmdhbW1hT3V0cHV0ID0gZmFsc2U7XG5cblx0Ly8gcGh5c2ljYWwgbGlnaHRzXG5cblx0dGhpcy5waHlzaWNhbGx5Q29ycmVjdExpZ2h0cyA9IGZhbHNlO1xuXG5cdC8vIHRvbmUgbWFwcGluZ1xuXG5cdHRoaXMudG9uZU1hcHBpbmcgPSBMaW5lYXJUb25lTWFwcGluZztcblx0dGhpcy50b25lTWFwcGluZ0V4cG9zdXJlID0gMS4wO1xuXHR0aGlzLnRvbmVNYXBwaW5nV2hpdGVQb2ludCA9IDEuMDtcblxuXHQvLyBtb3JwaHNcblxuXHR0aGlzLm1heE1vcnBoVGFyZ2V0cyA9IDg7XG5cdHRoaXMubWF4TW9ycGhOb3JtYWxzID0gNDtcblxuXHQvLyBpbnRlcm5hbCBwcm9wZXJ0aWVzXG5cblx0dmFyIF90aGlzID0gdGhpcyxcblxuXHRcdC8vIGludGVybmFsIHN0YXRlIGNhY2hlXG5cblx0XHRfY3VycmVudFByb2dyYW0gPSBudWxsLFxuXHRcdF9jdXJyZW50UmVuZGVyVGFyZ2V0ID0gbnVsbCxcblx0XHRfY3VycmVudEZyYW1lYnVmZmVyID0gbnVsbCxcblx0XHRfY3VycmVudE1hdGVyaWFsSWQgPSAtIDEsXG5cdFx0X2N1cnJlbnRHZW9tZXRyeVByb2dyYW0gPSAnJyxcblx0XHRfY3VycmVudENhbWVyYSA9IG51bGwsXG5cblx0XHRfY3VycmVudFNjaXNzb3IgPSBuZXcgVmVjdG9yNCgpLFxuXHRcdF9jdXJyZW50U2Npc3NvclRlc3QgPSBudWxsLFxuXG5cdFx0X2N1cnJlbnRWaWV3cG9ydCA9IG5ldyBWZWN0b3I0KCksXG5cblx0XHQvL1xuXG5cdFx0X3VzZWRUZXh0dXJlVW5pdHMgPSAwLFxuXG5cdFx0Ly9cblxuXHRcdF9jbGVhckNvbG9yID0gbmV3IENvbG9yKCAweDAwMDAwMCApLFxuXHRcdF9jbGVhckFscGhhID0gMCxcblxuXHRcdF93aWR0aCA9IF9jYW52YXMud2lkdGgsXG5cdFx0X2hlaWdodCA9IF9jYW52YXMuaGVpZ2h0LFxuXG5cdFx0X3BpeGVsUmF0aW8gPSAxLFxuXG5cdFx0X3NjaXNzb3IgPSBuZXcgVmVjdG9yNCggMCwgMCwgX3dpZHRoLCBfaGVpZ2h0ICksXG5cdFx0X3NjaXNzb3JUZXN0ID0gZmFsc2UsXG5cblx0XHRfdmlld3BvcnQgPSBuZXcgVmVjdG9yNCggMCwgMCwgX3dpZHRoLCBfaGVpZ2h0ICksXG5cblx0XHQvLyBmcnVzdHVtXG5cblx0XHRfZnJ1c3R1bSA9IG5ldyBGcnVzdHVtKCksXG5cblx0XHQvLyBjbGlwcGluZ1xuXG5cdFx0X2NsaXBwaW5nID0gbmV3IFdlYkdMQ2xpcHBpbmcoKSxcblx0XHRfY2xpcHBpbmdFbmFibGVkID0gZmFsc2UsXG5cdFx0X2xvY2FsQ2xpcHBpbmdFbmFibGVkID0gZmFsc2UsXG5cblx0XHQvLyBjYW1lcmEgbWF0cmljZXMgY2FjaGVcblxuXHRcdF9wcm9qU2NyZWVuTWF0cml4ID0gbmV3IE1hdHJpeDQoKSxcblxuXHRcdF92ZWN0b3IzID0gbmV3IFZlY3RvcjMoKSxcblx0XHRfbWF0cml4NCA9IG5ldyBNYXRyaXg0KCksXG5cdFx0X21hdHJpeDQyID0gbmV3IE1hdHJpeDQoKSxcblxuXHRcdC8vIGxpZ2h0IGFycmF5cyBjYWNoZVxuXG5cdFx0X2xpZ2h0cyA9IHtcblxuXHRcdFx0aGFzaDogJycsXG5cblx0XHRcdGFtYmllbnQ6IFsgMCwgMCwgMCBdLFxuXHRcdFx0ZGlyZWN0aW9uYWw6IFtdLFxuXHRcdFx0ZGlyZWN0aW9uYWxTaGFkb3dNYXA6IFtdLFxuXHRcdFx0ZGlyZWN0aW9uYWxTaGFkb3dNYXRyaXg6IFtdLFxuXHRcdFx0c3BvdDogW10sXG5cdFx0XHRzcG90U2hhZG93TWFwOiBbXSxcblx0XHRcdHNwb3RTaGFkb3dNYXRyaXg6IFtdLFxuXHRcdFx0cmVjdEFyZWE6IFtdLFxuXHRcdFx0cG9pbnQ6IFtdLFxuXHRcdFx0cG9pbnRTaGFkb3dNYXA6IFtdLFxuXHRcdFx0cG9pbnRTaGFkb3dNYXRyaXg6IFtdLFxuXHRcdFx0aGVtaTogW10sXG5cblx0XHRcdHNoYWRvd3M6IFtdXG5cblx0XHR9LFxuXG5cdFx0Ly8gaW5mb1xuXG5cdFx0X2luZm9NZW1vcnkgPSB7XG5cdFx0XHRnZW9tZXRyaWVzOiAwLFxuXHRcdFx0dGV4dHVyZXM6IDBcblx0XHR9LFxuXG5cdFx0X2luZm9SZW5kZXIgPSB7XG5cblx0XHRcdGZyYW1lOiAwLFxuXHRcdFx0Y2FsbHM6IDAsXG5cdFx0XHR2ZXJ0aWNlczogMCxcblx0XHRcdGZhY2VzOiAwLFxuXHRcdFx0cG9pbnRzOiAwXG5cblx0XHR9O1xuXG5cdHRoaXMuaW5mbyA9IHtcblxuXHRcdHJlbmRlcjogX2luZm9SZW5kZXIsXG5cdFx0bWVtb3J5OiBfaW5mb01lbW9yeSxcblx0XHRwcm9ncmFtczogbnVsbFxuXG5cdH07XG5cblxuXHQvLyBpbml0aWFsaXplXG5cblx0dmFyIF9nbDtcblxuXHR0cnkge1xuXG5cdFx0dmFyIGNvbnRleHRBdHRyaWJ1dGVzID0ge1xuXHRcdFx0YWxwaGE6IF9hbHBoYSxcblx0XHRcdGRlcHRoOiBfZGVwdGgsXG5cdFx0XHRzdGVuY2lsOiBfc3RlbmNpbCxcblx0XHRcdGFudGlhbGlhczogX2FudGlhbGlhcyxcblx0XHRcdHByZW11bHRpcGxpZWRBbHBoYTogX3ByZW11bHRpcGxpZWRBbHBoYSxcblx0XHRcdHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogX3ByZXNlcnZlRHJhd2luZ0J1ZmZlclxuXHRcdH07XG5cblx0XHRfZ2wgPSBfY29udGV4dCB8fCBfY2FudmFzLmdldENvbnRleHQoICd3ZWJnbCcsIGNvbnRleHRBdHRyaWJ1dGVzICkgfHwgX2NhbnZhcy5nZXRDb250ZXh0KCAnZXhwZXJpbWVudGFsLXdlYmdsJywgY29udGV4dEF0dHJpYnV0ZXMgKTtcblxuXHRcdGlmICggX2dsID09PSBudWxsICkge1xuXG5cdFx0XHRpZiAoIF9jYW52YXMuZ2V0Q29udGV4dCggJ3dlYmdsJyApICE9PSBudWxsICkge1xuXG5cdFx0XHRcdHRocm93ICdFcnJvciBjcmVhdGluZyBXZWJHTCBjb250ZXh0IHdpdGggeW91ciBzZWxlY3RlZCBhdHRyaWJ1dGVzLic7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dGhyb3cgJ0Vycm9yIGNyZWF0aW5nIFdlYkdMIGNvbnRleHQuJztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gU29tZSBleHBlcmltZW50YWwtd2ViZ2wgaW1wbGVtZW50YXRpb25zIGRvIG5vdCBoYXZlIGdldFNoYWRlclByZWNpc2lvbkZvcm1hdFxuXG5cdFx0aWYgKCBfZ2wuZ2V0U2hhZGVyUHJlY2lzaW9uRm9ybWF0ID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdF9nbC5nZXRTaGFkZXJQcmVjaXNpb25Gb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0cmV0dXJuIHsgJ3JhbmdlTWluJzogMSwgJ3JhbmdlTWF4JzogMSwgJ3ByZWNpc2lvbic6IDEgfTtcblxuXHRcdFx0fTtcblxuXHRcdH1cblxuXHRcdF9jYW52YXMuYWRkRXZlbnRMaXN0ZW5lciggJ3dlYmdsY29udGV4dGxvc3QnLCBvbkNvbnRleHRMb3N0LCBmYWxzZSApO1xuXG5cdH0gY2F0Y2ggKCBlcnJvciApIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAnICsgZXJyb3IgKTtcblxuXHR9XG5cblx0dmFyIGV4dGVuc2lvbnMgPSBuZXcgV2ViR0xFeHRlbnNpb25zKCBfZ2wgKTtcblxuXHRleHRlbnNpb25zLmdldCggJ1dFQkdMX2RlcHRoX3RleHR1cmUnICk7XG5cdGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3RleHR1cmVfZmxvYXQnICk7XG5cdGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3RleHR1cmVfZmxvYXRfbGluZWFyJyApO1xuXHRleHRlbnNpb25zLmdldCggJ09FU190ZXh0dXJlX2hhbGZfZmxvYXQnICk7XG5cdGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3RleHR1cmVfaGFsZl9mbG9hdF9saW5lYXInICk7XG5cdGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3N0YW5kYXJkX2Rlcml2YXRpdmVzJyApO1xuXHRleHRlbnNpb25zLmdldCggJ0FOR0xFX2luc3RhbmNlZF9hcnJheXMnICk7XG5cblx0aWYgKCBleHRlbnNpb25zLmdldCggJ09FU19lbGVtZW50X2luZGV4X3VpbnQnICkgKSB7XG5cblx0XHRCdWZmZXJHZW9tZXRyeS5NYXhJbmRleCA9IDQyOTQ5NjcyOTY7XG5cblx0fVxuXG5cdHZhciBjYXBhYmlsaXRpZXMgPSBuZXcgV2ViR0xDYXBhYmlsaXRpZXMoIF9nbCwgZXh0ZW5zaW9ucywgcGFyYW1ldGVycyApO1xuXG5cdHZhciBzdGF0ZSA9IG5ldyBXZWJHTFN0YXRlKCBfZ2wsIGV4dGVuc2lvbnMsIHBhcmFtVGhyZWVUb0dMICk7XG5cblx0dmFyIHByb3BlcnRpZXMgPSBuZXcgV2ViR0xQcm9wZXJ0aWVzKCk7XG5cdHZhciB0ZXh0dXJlcyA9IG5ldyBXZWJHTFRleHR1cmVzKCBfZ2wsIGV4dGVuc2lvbnMsIHN0YXRlLCBwcm9wZXJ0aWVzLCBjYXBhYmlsaXRpZXMsIHBhcmFtVGhyZWVUb0dMLCBfaW5mb01lbW9yeSApO1xuXHR2YXIgYXR0cmlidXRlcyA9IG5ldyBXZWJHTEF0dHJpYnV0ZXMoIF9nbCApO1xuXHR2YXIgZ2VvbWV0cmllcyA9IG5ldyBXZWJHTEdlb21ldHJpZXMoIF9nbCwgYXR0cmlidXRlcywgX2luZm9NZW1vcnkgKTtcblx0dmFyIG9iamVjdHMgPSBuZXcgV2ViR0xPYmplY3RzKCBfZ2wsIGdlb21ldHJpZXMsIF9pbmZvUmVuZGVyICk7XG5cdHZhciBwcm9ncmFtQ2FjaGUgPSBuZXcgV2ViR0xQcm9ncmFtcyggdGhpcywgY2FwYWJpbGl0aWVzICk7XG5cdHZhciBsaWdodENhY2hlID0gbmV3IFdlYkdMTGlnaHRzKCk7XG5cdHZhciByZW5kZXJMaXN0cyA9IG5ldyBXZWJHTFJlbmRlckxpc3RzKCk7XG5cblx0dGhpcy5pbmZvLnByb2dyYW1zID0gcHJvZ3JhbUNhY2hlLnByb2dyYW1zO1xuXG5cdHZhciBidWZmZXJSZW5kZXJlciA9IG5ldyBXZWJHTEJ1ZmZlclJlbmRlcmVyKCBfZ2wsIGV4dGVuc2lvbnMsIF9pbmZvUmVuZGVyICk7XG5cdHZhciBpbmRleGVkQnVmZmVyUmVuZGVyZXIgPSBuZXcgV2ViR0xJbmRleGVkQnVmZmVyUmVuZGVyZXIoIF9nbCwgZXh0ZW5zaW9ucywgX2luZm9SZW5kZXIgKTtcblxuXHQvL1xuXG5cdHZhciBiYWNrZ3JvdW5kUGxhbmVDYW1lcmEsIGJhY2tncm91bmRQbGFuZU1lc2g7XG5cdHZhciBiYWNrZ3JvdW5kQm94Q2FtZXJhLCBiYWNrZ3JvdW5kQm94TWVzaDtcblxuXHQvL1xuXG5cdGZ1bmN0aW9uIGdldFRhcmdldFBpeGVsUmF0aW8oKSB7XG5cblx0XHRyZXR1cm4gX2N1cnJlbnRSZW5kZXJUYXJnZXQgPT09IG51bGwgPyBfcGl4ZWxSYXRpbyA6IDE7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHNldERlZmF1bHRHTFN0YXRlKCkge1xuXG5cdFx0c3RhdGUuaW5pdCgpO1xuXG5cdFx0c3RhdGUuc2Npc3NvciggX2N1cnJlbnRTY2lzc29yLmNvcHkoIF9zY2lzc29yICkubXVsdGlwbHlTY2FsYXIoIF9waXhlbFJhdGlvICkgKTtcblx0XHRzdGF0ZS52aWV3cG9ydCggX2N1cnJlbnRWaWV3cG9ydC5jb3B5KCBfdmlld3BvcnQgKS5tdWx0aXBseVNjYWxhciggX3BpeGVsUmF0aW8gKSApO1xuXG5cdFx0c3RhdGUuYnVmZmVycy5jb2xvci5zZXRDbGVhciggX2NsZWFyQ29sb3IuciwgX2NsZWFyQ29sb3IuZywgX2NsZWFyQ29sb3IuYiwgX2NsZWFyQWxwaGEsIF9wcmVtdWx0aXBsaWVkQWxwaGEgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVzZXRHTFN0YXRlKCkge1xuXG5cdFx0X2N1cnJlbnRQcm9ncmFtID0gbnVsbDtcblx0XHRfY3VycmVudENhbWVyYSA9IG51bGw7XG5cblx0XHRfY3VycmVudEdlb21ldHJ5UHJvZ3JhbSA9ICcnO1xuXHRcdF9jdXJyZW50TWF0ZXJpYWxJZCA9IC0gMTtcblxuXHRcdHN0YXRlLnJlc2V0KCk7XG5cblx0fVxuXG5cdHNldERlZmF1bHRHTFN0YXRlKCk7XG5cblx0dGhpcy5jb250ZXh0ID0gX2dsO1xuXHR0aGlzLmNhcGFiaWxpdGllcyA9IGNhcGFiaWxpdGllcztcblx0dGhpcy5leHRlbnNpb25zID0gZXh0ZW5zaW9ucztcblx0dGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcblx0dGhpcy5zdGF0ZSA9IHN0YXRlO1xuXG5cdC8vIHNoYWRvdyBtYXBcblxuXHR2YXIgc2hhZG93TWFwID0gbmV3IFdlYkdMU2hhZG93TWFwKCB0aGlzLCBfbGlnaHRzLCBvYmplY3RzLCBjYXBhYmlsaXRpZXMgKTtcblxuXHR0aGlzLnNoYWRvd01hcCA9IHNoYWRvd01hcDtcblxuXG5cdC8vIFBsdWdpbnNcblxuXHR2YXIgc3ByaXRlUGx1Z2luID0gbmV3IFNwcml0ZVBsdWdpbiggdGhpcywgc3ByaXRlcyApO1xuXHR2YXIgbGVuc0ZsYXJlUGx1Z2luID0gbmV3IExlbnNGbGFyZVBsdWdpbiggdGhpcywgbGVuc0ZsYXJlcyApO1xuXG5cdC8vIEFQSVxuXG5cdHRoaXMuZ2V0Q29udGV4dCA9IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBfZ2w7XG5cblx0fTtcblxuXHR0aGlzLmdldENvbnRleHRBdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIF9nbC5nZXRDb250ZXh0QXR0cmlidXRlcygpO1xuXG5cdH07XG5cblx0dGhpcy5mb3JjZUNvbnRleHRMb3NzID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGV4dGVuc2lvbiA9IGV4dGVuc2lvbnMuZ2V0KCAnV0VCR0xfbG9zZV9jb250ZXh0JyApO1xuXHRcdGlmICggZXh0ZW5zaW9uICkgZXh0ZW5zaW9uLmxvc2VDb250ZXh0KCk7XG5cblx0fTtcblxuXHR0aGlzLmdldE1heEFuaXNvdHJvcHkgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gY2FwYWJpbGl0aWVzLmdldE1heEFuaXNvdHJvcHkoKTtcblxuXHR9O1xuXG5cdHRoaXMuZ2V0UHJlY2lzaW9uID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIGNhcGFiaWxpdGllcy5wcmVjaXNpb247XG5cblx0fTtcblxuXHR0aGlzLmdldFBpeGVsUmF0aW8gPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gX3BpeGVsUmF0aW87XG5cblx0fTtcblxuXHR0aGlzLnNldFBpeGVsUmF0aW8gPSBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0aWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkICkgcmV0dXJuO1xuXG5cdFx0X3BpeGVsUmF0aW8gPSB2YWx1ZTtcblxuXHRcdHRoaXMuc2V0U2l6ZSggX3ZpZXdwb3J0LnosIF92aWV3cG9ydC53LCBmYWxzZSApO1xuXG5cdH07XG5cblx0dGhpcy5nZXRTaXplID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHdpZHRoOiBfd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IF9oZWlnaHRcblx0XHR9O1xuXG5cdH07XG5cblx0dGhpcy5zZXRTaXplID0gZnVuY3Rpb24gKCB3aWR0aCwgaGVpZ2h0LCB1cGRhdGVTdHlsZSApIHtcblxuXHRcdF93aWR0aCA9IHdpZHRoO1xuXHRcdF9oZWlnaHQgPSBoZWlnaHQ7XG5cblx0XHRfY2FudmFzLndpZHRoID0gd2lkdGggKiBfcGl4ZWxSYXRpbztcblx0XHRfY2FudmFzLmhlaWdodCA9IGhlaWdodCAqIF9waXhlbFJhdGlvO1xuXG5cdFx0aWYgKCB1cGRhdGVTdHlsZSAhPT0gZmFsc2UgKSB7XG5cblx0XHRcdF9jYW52YXMuc3R5bGUud2lkdGggPSB3aWR0aCArICdweCc7XG5cdFx0XHRfY2FudmFzLnN0eWxlLmhlaWdodCA9IGhlaWdodCArICdweCc7XG5cblx0XHR9XG5cblx0XHR0aGlzLnNldFZpZXdwb3J0KCAwLCAwLCB3aWR0aCwgaGVpZ2h0ICk7XG5cblx0fTtcblxuXHR0aGlzLnNldFZpZXdwb3J0ID0gZnVuY3Rpb24gKCB4LCB5LCB3aWR0aCwgaGVpZ2h0ICkge1xuXG5cdFx0c3RhdGUudmlld3BvcnQoIF92aWV3cG9ydC5zZXQoIHgsIHksIHdpZHRoLCBoZWlnaHQgKSApO1xuXG5cdH07XG5cblx0dGhpcy5zZXRTY2lzc29yID0gZnVuY3Rpb24gKCB4LCB5LCB3aWR0aCwgaGVpZ2h0ICkge1xuXG5cdFx0c3RhdGUuc2Npc3NvciggX3NjaXNzb3Iuc2V0KCB4LCB5LCB3aWR0aCwgaGVpZ2h0ICkgKTtcblxuXHR9O1xuXG5cdHRoaXMuc2V0U2Npc3NvclRlc3QgPSBmdW5jdGlvbiAoIGJvb2xlYW4gKSB7XG5cblx0XHRzdGF0ZS5zZXRTY2lzc29yVGVzdCggX3NjaXNzb3JUZXN0ID0gYm9vbGVhbiApO1xuXG5cdH07XG5cblx0Ly8gQ2xlYXJpbmdcblxuXHR0aGlzLmdldENsZWFyQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gX2NsZWFyQ29sb3I7XG5cblx0fTtcblxuXHR0aGlzLnNldENsZWFyQ29sb3IgPSBmdW5jdGlvbiAoIGNvbG9yLCBhbHBoYSApIHtcblxuXHRcdF9jbGVhckNvbG9yLnNldCggY29sb3IgKTtcblxuXHRcdF9jbGVhckFscGhhID0gYWxwaGEgIT09IHVuZGVmaW5lZCA/IGFscGhhIDogMTtcblxuXHRcdHN0YXRlLmJ1ZmZlcnMuY29sb3Iuc2V0Q2xlYXIoIF9jbGVhckNvbG9yLnIsIF9jbGVhckNvbG9yLmcsIF9jbGVhckNvbG9yLmIsIF9jbGVhckFscGhhLCBfcHJlbXVsdGlwbGllZEFscGhhICk7XG5cblx0fTtcblxuXHR0aGlzLmdldENsZWFyQWxwaGEgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gX2NsZWFyQWxwaGE7XG5cblx0fTtcblxuXHR0aGlzLnNldENsZWFyQWxwaGEgPSBmdW5jdGlvbiAoIGFscGhhICkge1xuXG5cdFx0X2NsZWFyQWxwaGEgPSBhbHBoYTtcblxuXHRcdHN0YXRlLmJ1ZmZlcnMuY29sb3Iuc2V0Q2xlYXIoIF9jbGVhckNvbG9yLnIsIF9jbGVhckNvbG9yLmcsIF9jbGVhckNvbG9yLmIsIF9jbGVhckFscGhhLCBfcHJlbXVsdGlwbGllZEFscGhhICk7XG5cblx0fTtcblxuXHR0aGlzLmNsZWFyID0gZnVuY3Rpb24gKCBjb2xvciwgZGVwdGgsIHN0ZW5jaWwgKSB7XG5cblx0XHR2YXIgYml0cyA9IDA7XG5cblx0XHRpZiAoIGNvbG9yID09PSB1bmRlZmluZWQgfHwgY29sb3IgKSBiaXRzIHw9IF9nbC5DT0xPUl9CVUZGRVJfQklUO1xuXHRcdGlmICggZGVwdGggPT09IHVuZGVmaW5lZCB8fCBkZXB0aCApIGJpdHMgfD0gX2dsLkRFUFRIX0JVRkZFUl9CSVQ7XG5cdFx0aWYgKCBzdGVuY2lsID09PSB1bmRlZmluZWQgfHwgc3RlbmNpbCApIGJpdHMgfD0gX2dsLlNURU5DSUxfQlVGRkVSX0JJVDtcblxuXHRcdF9nbC5jbGVhciggYml0cyApO1xuXG5cdH07XG5cblx0dGhpcy5jbGVhckNvbG9yID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5jbGVhciggdHJ1ZSwgZmFsc2UsIGZhbHNlICk7XG5cblx0fTtcblxuXHR0aGlzLmNsZWFyRGVwdGggPSBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLmNsZWFyKCBmYWxzZSwgdHJ1ZSwgZmFsc2UgKTtcblxuXHR9O1xuXG5cdHRoaXMuY2xlYXJTdGVuY2lsID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5jbGVhciggZmFsc2UsIGZhbHNlLCB0cnVlICk7XG5cblx0fTtcblxuXHR0aGlzLmNsZWFyVGFyZ2V0ID0gZnVuY3Rpb24gKCByZW5kZXJUYXJnZXQsIGNvbG9yLCBkZXB0aCwgc3RlbmNpbCApIHtcblxuXHRcdHRoaXMuc2V0UmVuZGVyVGFyZ2V0KCByZW5kZXJUYXJnZXQgKTtcblx0XHR0aGlzLmNsZWFyKCBjb2xvciwgZGVwdGgsIHN0ZW5jaWwgKTtcblxuXHR9O1xuXG5cdC8vIFJlc2V0XG5cblx0dGhpcy5yZXNldEdMU3RhdGUgPSByZXNldEdMU3RhdGU7XG5cblx0dGhpcy5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0X2NhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCAnd2ViZ2xjb250ZXh0bG9zdCcsIG9uQ29udGV4dExvc3QsIGZhbHNlICk7XG5cblx0XHRyZW5kZXJMaXN0cy5kaXNwb3NlKCk7XG5cblx0fTtcblxuXHQvLyBFdmVudHNcblxuXHRmdW5jdGlvbiBvbkNvbnRleHRMb3N0KCBldmVudCApIHtcblxuXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRyZXNldEdMU3RhdGUoKTtcblx0XHRzZXREZWZhdWx0R0xTdGF0ZSgpO1xuXG5cdFx0cHJvcGVydGllcy5jbGVhcigpO1xuXHRcdG9iamVjdHMuY2xlYXIoKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gb25NYXRlcmlhbERpc3Bvc2UoIGV2ZW50ICkge1xuXG5cdFx0dmFyIG1hdGVyaWFsID0gZXZlbnQudGFyZ2V0O1xuXG5cdFx0bWF0ZXJpYWwucmVtb3ZlRXZlbnRMaXN0ZW5lciggJ2Rpc3Bvc2UnLCBvbk1hdGVyaWFsRGlzcG9zZSApO1xuXG5cdFx0ZGVhbGxvY2F0ZU1hdGVyaWFsKCBtYXRlcmlhbCApO1xuXG5cdH1cblxuXHQvLyBCdWZmZXIgZGVhbGxvY2F0aW9uXG5cblx0ZnVuY3Rpb24gZGVhbGxvY2F0ZU1hdGVyaWFsKCBtYXRlcmlhbCApIHtcblxuXHRcdHJlbGVhc2VNYXRlcmlhbFByb2dyYW1SZWZlcmVuY2UoIG1hdGVyaWFsICk7XG5cblx0XHRwcm9wZXJ0aWVzLnJlbW92ZSggbWF0ZXJpYWwgKTtcblxuXHR9XG5cblxuXHRmdW5jdGlvbiByZWxlYXNlTWF0ZXJpYWxQcm9ncmFtUmVmZXJlbmNlKCBtYXRlcmlhbCApIHtcblxuXHRcdHZhciBwcm9ncmFtSW5mbyA9IHByb3BlcnRpZXMuZ2V0KCBtYXRlcmlhbCApLnByb2dyYW07XG5cblx0XHRtYXRlcmlhbC5wcm9ncmFtID0gdW5kZWZpbmVkO1xuXG5cdFx0aWYgKCBwcm9ncmFtSW5mbyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRwcm9ncmFtQ2FjaGUucmVsZWFzZVByb2dyYW0oIHByb2dyYW1JbmZvICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIEJ1ZmZlciByZW5kZXJpbmdcblxuXHRmdW5jdGlvbiByZW5kZXJPYmplY3RJbW1lZGlhdGUoIG9iamVjdCwgcHJvZ3JhbSwgbWF0ZXJpYWwgKSB7XG5cblx0XHRvYmplY3QucmVuZGVyKCBmdW5jdGlvbiAoIG9iamVjdCApIHtcblxuXHRcdFx0X3RoaXMucmVuZGVyQnVmZmVySW1tZWRpYXRlKCBvYmplY3QsIHByb2dyYW0sIG1hdGVyaWFsICk7XG5cblx0XHR9ICk7XG5cblx0fVxuXG5cdHRoaXMucmVuZGVyQnVmZmVySW1tZWRpYXRlID0gZnVuY3Rpb24gKCBvYmplY3QsIHByb2dyYW0sIG1hdGVyaWFsICkge1xuXG5cdFx0c3RhdGUuaW5pdEF0dHJpYnV0ZXMoKTtcblxuXHRcdHZhciBidWZmZXJzID0gcHJvcGVydGllcy5nZXQoIG9iamVjdCApO1xuXG5cdFx0aWYgKCBvYmplY3QuaGFzUG9zaXRpb25zICYmICEgYnVmZmVycy5wb3NpdGlvbiApIGJ1ZmZlcnMucG9zaXRpb24gPSBfZ2wuY3JlYXRlQnVmZmVyKCk7XG5cdFx0aWYgKCBvYmplY3QuaGFzTm9ybWFscyAmJiAhIGJ1ZmZlcnMubm9ybWFsICkgYnVmZmVycy5ub3JtYWwgPSBfZ2wuY3JlYXRlQnVmZmVyKCk7XG5cdFx0aWYgKCBvYmplY3QuaGFzVXZzICYmICEgYnVmZmVycy51diApIGJ1ZmZlcnMudXYgPSBfZ2wuY3JlYXRlQnVmZmVyKCk7XG5cdFx0aWYgKCBvYmplY3QuaGFzQ29sb3JzICYmICEgYnVmZmVycy5jb2xvciApIGJ1ZmZlcnMuY29sb3IgPSBfZ2wuY3JlYXRlQnVmZmVyKCk7XG5cblx0XHR2YXIgcHJvZ3JhbUF0dHJpYnV0ZXMgPSBwcm9ncmFtLmdldEF0dHJpYnV0ZXMoKTtcblxuXHRcdGlmICggb2JqZWN0Lmhhc1Bvc2l0aW9ucyApIHtcblxuXHRcdFx0X2dsLmJpbmRCdWZmZXIoIF9nbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcnMucG9zaXRpb24gKTtcblx0XHRcdF9nbC5idWZmZXJEYXRhKCBfZ2wuQVJSQVlfQlVGRkVSLCBvYmplY3QucG9zaXRpb25BcnJheSwgX2dsLkRZTkFNSUNfRFJBVyApO1xuXG5cdFx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIHByb2dyYW1BdHRyaWJ1dGVzLnBvc2l0aW9uICk7XG5cdFx0XHRfZ2wudmVydGV4QXR0cmliUG9pbnRlciggcHJvZ3JhbUF0dHJpYnV0ZXMucG9zaXRpb24sIDMsIF9nbC5GTE9BVCwgZmFsc2UsIDAsIDAgKTtcblxuXHRcdH1cblxuXHRcdGlmICggb2JqZWN0Lmhhc05vcm1hbHMgKSB7XG5cblx0XHRcdF9nbC5iaW5kQnVmZmVyKCBfZ2wuQVJSQVlfQlVGRkVSLCBidWZmZXJzLm5vcm1hbCApO1xuXG5cdFx0XHRpZiAoICEgbWF0ZXJpYWwuaXNNZXNoUGhvbmdNYXRlcmlhbCAmJlxuXHRcdFx0XHQhIG1hdGVyaWFsLmlzTWVzaFN0YW5kYXJkTWF0ZXJpYWwgJiZcblx0XHRcdFx0ISBtYXRlcmlhbC5pc01lc2hOb3JtYWxNYXRlcmlhbCAmJlxuXHRcdFx0XHRtYXRlcmlhbC5zaGFkaW5nID09PSBGbGF0U2hhZGluZyApIHtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBvYmplY3QuY291bnQgKiAzOyBpIDwgbDsgaSArPSA5ICkge1xuXG5cdFx0XHRcdFx0dmFyIGFycmF5ID0gb2JqZWN0Lm5vcm1hbEFycmF5O1xuXG5cdFx0XHRcdFx0dmFyIG54ID0gKCBhcnJheVsgaSArIDAgXSArIGFycmF5WyBpICsgMyBdICsgYXJyYXlbIGkgKyA2IF0gKSAvIDM7XG5cdFx0XHRcdFx0dmFyIG55ID0gKCBhcnJheVsgaSArIDEgXSArIGFycmF5WyBpICsgNCBdICsgYXJyYXlbIGkgKyA3IF0gKSAvIDM7XG5cdFx0XHRcdFx0dmFyIG56ID0gKCBhcnJheVsgaSArIDIgXSArIGFycmF5WyBpICsgNSBdICsgYXJyYXlbIGkgKyA4IF0gKSAvIDM7XG5cblx0XHRcdFx0XHRhcnJheVsgaSArIDAgXSA9IG54O1xuXHRcdFx0XHRcdGFycmF5WyBpICsgMSBdID0gbnk7XG5cdFx0XHRcdFx0YXJyYXlbIGkgKyAyIF0gPSBuejtcblxuXHRcdFx0XHRcdGFycmF5WyBpICsgMyBdID0gbng7XG5cdFx0XHRcdFx0YXJyYXlbIGkgKyA0IF0gPSBueTtcblx0XHRcdFx0XHRhcnJheVsgaSArIDUgXSA9IG56O1xuXG5cdFx0XHRcdFx0YXJyYXlbIGkgKyA2IF0gPSBueDtcblx0XHRcdFx0XHRhcnJheVsgaSArIDcgXSA9IG55O1xuXHRcdFx0XHRcdGFycmF5WyBpICsgOCBdID0gbno7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdF9nbC5idWZmZXJEYXRhKCBfZ2wuQVJSQVlfQlVGRkVSLCBvYmplY3Qubm9ybWFsQXJyYXksIF9nbC5EWU5BTUlDX0RSQVcgKTtcblxuXHRcdFx0c3RhdGUuZW5hYmxlQXR0cmlidXRlKCBwcm9ncmFtQXR0cmlidXRlcy5ub3JtYWwgKTtcblxuXHRcdFx0X2dsLnZlcnRleEF0dHJpYlBvaW50ZXIoIHByb2dyYW1BdHRyaWJ1dGVzLm5vcm1hbCwgMywgX2dsLkZMT0FULCBmYWxzZSwgMCwgMCApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBvYmplY3QuaGFzVXZzICYmIG1hdGVyaWFsLm1hcCApIHtcblxuXHRcdFx0X2dsLmJpbmRCdWZmZXIoIF9nbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcnMudXYgKTtcblx0XHRcdF9nbC5idWZmZXJEYXRhKCBfZ2wuQVJSQVlfQlVGRkVSLCBvYmplY3QudXZBcnJheSwgX2dsLkRZTkFNSUNfRFJBVyApO1xuXG5cdFx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIHByb2dyYW1BdHRyaWJ1dGVzLnV2ICk7XG5cblx0XHRcdF9nbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKCBhdHRyaWJ1dGVzLnV2LCAyLCBfZ2wuRkxPQVQsIGZhbHNlLCAwLCAwICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIG9iamVjdC5oYXNDb2xvcnMgJiYgbWF0ZXJpYWwudmVydGV4Q29sb3JzICE9PSBOb0NvbG9ycyApIHtcblxuXHRcdFx0X2dsLmJpbmRCdWZmZXIoIF9nbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcnMuY29sb3IgKTtcblx0XHRcdF9nbC5idWZmZXJEYXRhKCBfZ2wuQVJSQVlfQlVGRkVSLCBvYmplY3QuY29sb3JBcnJheSwgX2dsLkRZTkFNSUNfRFJBVyApO1xuXG5cdFx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIHByb2dyYW1BdHRyaWJ1dGVzLmNvbG9yICk7XG5cblx0XHRcdF9nbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKCBwcm9ncmFtQXR0cmlidXRlcy5jb2xvciwgMywgX2dsLkZMT0FULCBmYWxzZSwgMCwgMCApO1xuXG5cdFx0fVxuXG5cdFx0c3RhdGUuZGlzYWJsZVVudXNlZEF0dHJpYnV0ZXMoKTtcblxuXHRcdF9nbC5kcmF3QXJyYXlzKCBfZ2wuVFJJQU5HTEVTLCAwLCBvYmplY3QuY291bnQgKTtcblxuXHRcdG9iamVjdC5jb3VudCA9IDA7XG5cblx0fTtcblxuXHRmdW5jdGlvbiBhYnNOdW1lcmljYWxTb3J0KCBhLCBiICkge1xuXG5cdFx0cmV0dXJuIE1hdGguYWJzKCBiWyAwIF0gKSAtIE1hdGguYWJzKCBhWyAwIF0gKTtcblxuXHR9XG5cblx0dGhpcy5yZW5kZXJCdWZmZXJEaXJlY3QgPSBmdW5jdGlvbiAoIGNhbWVyYSwgZm9nLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIG9iamVjdCwgZ3JvdXAgKSB7XG5cblx0XHRzdGF0ZS5zZXRNYXRlcmlhbCggbWF0ZXJpYWwgKTtcblxuXHRcdHZhciBwcm9ncmFtID0gc2V0UHJvZ3JhbSggY2FtZXJhLCBmb2csIG1hdGVyaWFsLCBvYmplY3QgKTtcblx0XHR2YXIgZ2VvbWV0cnlQcm9ncmFtID0gZ2VvbWV0cnkuaWQgKyAnXycgKyBwcm9ncmFtLmlkICsgJ18nICsgKCBtYXRlcmlhbC53aXJlZnJhbWUgPT09IHRydWUgKTtcblxuXHRcdHZhciB1cGRhdGVCdWZmZXJzID0gZmFsc2U7XG5cblx0XHRpZiAoIGdlb21ldHJ5UHJvZ3JhbSAhPT0gX2N1cnJlbnRHZW9tZXRyeVByb2dyYW0gKSB7XG5cblx0XHRcdF9jdXJyZW50R2VvbWV0cnlQcm9ncmFtID0gZ2VvbWV0cnlQcm9ncmFtO1xuXHRcdFx0dXBkYXRlQnVmZmVycyA9IHRydWU7XG5cblx0XHR9XG5cblx0XHQvLyBtb3JwaCB0YXJnZXRzXG5cblx0XHR2YXIgbW9ycGhUYXJnZXRJbmZsdWVuY2VzID0gb2JqZWN0Lm1vcnBoVGFyZ2V0SW5mbHVlbmNlcztcblxuXHRcdGlmICggbW9ycGhUYXJnZXRJbmZsdWVuY2VzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIFRPRE8gUmVtb3ZlIGFsbG9jYXRpb25zXG5cblx0XHRcdHZhciBhY3RpdmVJbmZsdWVuY2VzID0gW107XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IG1vcnBoVGFyZ2V0SW5mbHVlbmNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdHZhciBpbmZsdWVuY2UgPSBtb3JwaFRhcmdldEluZmx1ZW5jZXNbIGkgXTtcblx0XHRcdFx0YWN0aXZlSW5mbHVlbmNlcy5wdXNoKCBbIGluZmx1ZW5jZSwgaSBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0YWN0aXZlSW5mbHVlbmNlcy5zb3J0KCBhYnNOdW1lcmljYWxTb3J0ICk7XG5cblx0XHRcdGlmICggYWN0aXZlSW5mbHVlbmNlcy5sZW5ndGggPiA4ICkge1xuXG5cdFx0XHRcdGFjdGl2ZUluZmx1ZW5jZXMubGVuZ3RoID0gODtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbW9ycGhBdHRyaWJ1dGVzID0gZ2VvbWV0cnkubW9ycGhBdHRyaWJ1dGVzO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBhY3RpdmVJbmZsdWVuY2VzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGluZmx1ZW5jZSA9IGFjdGl2ZUluZmx1ZW5jZXNbIGkgXTtcblx0XHRcdFx0bW9ycGhJbmZsdWVuY2VzWyBpIF0gPSBpbmZsdWVuY2VbIDAgXTtcblxuXHRcdFx0XHRpZiAoIGluZmx1ZW5jZVsgMCBdICE9PSAwICkge1xuXG5cdFx0XHRcdFx0dmFyIGluZGV4ID0gaW5mbHVlbmNlWyAxIF07XG5cblx0XHRcdFx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoVGFyZ2V0cyA9PT0gdHJ1ZSAmJiBtb3JwaEF0dHJpYnV0ZXMucG9zaXRpb24gKSBnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdtb3JwaFRhcmdldCcgKyBpLCBtb3JwaEF0dHJpYnV0ZXMucG9zaXRpb25bIGluZGV4IF0gKTtcblx0XHRcdFx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoTm9ybWFscyA9PT0gdHJ1ZSAmJiBtb3JwaEF0dHJpYnV0ZXMubm9ybWFsICkgZ2VvbWV0cnkuYWRkQXR0cmlidXRlKCAnbW9ycGhOb3JtYWwnICsgaSwgbW9ycGhBdHRyaWJ1dGVzLm5vcm1hbFsgaW5kZXggXSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoVGFyZ2V0cyA9PT0gdHJ1ZSApIGdlb21ldHJ5LnJlbW92ZUF0dHJpYnV0ZSggJ21vcnBoVGFyZ2V0JyArIGkgKTtcblx0XHRcdFx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoTm9ybWFscyA9PT0gdHJ1ZSApIGdlb21ldHJ5LnJlbW92ZUF0dHJpYnV0ZSggJ21vcnBoTm9ybWFsJyArIGkgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggdmFyIGkgPSBhY3RpdmVJbmZsdWVuY2VzLmxlbmd0aCwgaWwgPSBtb3JwaEluZmx1ZW5jZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0bW9ycGhJbmZsdWVuY2VzWyBpIF0gPSAwLjA7XG5cblx0XHRcdH1cblxuXHRcdFx0cHJvZ3JhbS5nZXRVbmlmb3JtcygpLnNldFZhbHVlKCBfZ2wsICdtb3JwaFRhcmdldEluZmx1ZW5jZXMnLCBtb3JwaEluZmx1ZW5jZXMgKTtcblxuXHRcdFx0dXBkYXRlQnVmZmVycyA9IHRydWU7XG5cblx0XHR9XG5cblx0XHQvL1xuXG5cdFx0dmFyIGluZGV4ID0gZ2VvbWV0cnkuaW5kZXg7XG5cdFx0dmFyIHBvc2l0aW9uID0gZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbjtcblx0XHR2YXIgcmFuZ2VGYWN0b3IgPSAxO1xuXG5cdFx0aWYgKCBtYXRlcmlhbC53aXJlZnJhbWUgPT09IHRydWUgKSB7XG5cblx0XHRcdGluZGV4ID0gZ2VvbWV0cmllcy5nZXRXaXJlZnJhbWVBdHRyaWJ1dGUoIGdlb21ldHJ5ICk7XG5cdFx0XHRyYW5nZUZhY3RvciA9IDI7XG5cblx0XHR9XG5cblx0XHR2YXIgcmVuZGVyZXIgPSBidWZmZXJSZW5kZXJlcjtcblxuXHRcdGlmICggaW5kZXggIT09IG51bGwgKSB7XG5cblx0XHRcdHJlbmRlcmVyID0gaW5kZXhlZEJ1ZmZlclJlbmRlcmVyO1xuXHRcdFx0cmVuZGVyZXIuc2V0SW5kZXgoIGluZGV4ICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIHVwZGF0ZUJ1ZmZlcnMgKSB7XG5cblx0XHRcdHNldHVwVmVydGV4QXR0cmlidXRlcyggbWF0ZXJpYWwsIHByb2dyYW0sIGdlb21ldHJ5ICk7XG5cblx0XHRcdGlmICggaW5kZXggIT09IG51bGwgKSB7XG5cblx0XHRcdFx0X2dsLmJpbmRCdWZmZXIoIF9nbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYXR0cmlidXRlcy5nZXQoIGluZGV4ICkuYnVmZmVyICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdC8vXG5cblx0XHR2YXIgZGF0YUNvdW50ID0gMDtcblxuXHRcdGlmICggaW5kZXggIT09IG51bGwgKSB7XG5cblx0XHRcdGRhdGFDb3VudCA9IGluZGV4LmNvdW50O1xuXG5cdFx0fSBlbHNlIGlmICggcG9zaXRpb24gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0ZGF0YUNvdW50ID0gcG9zaXRpb24uY291bnQ7XG5cblx0XHR9XG5cblx0XHR2YXIgcmFuZ2VTdGFydCA9IGdlb21ldHJ5LmRyYXdSYW5nZS5zdGFydCAqIHJhbmdlRmFjdG9yO1xuXHRcdHZhciByYW5nZUNvdW50ID0gZ2VvbWV0cnkuZHJhd1JhbmdlLmNvdW50ICogcmFuZ2VGYWN0b3I7XG5cblx0XHR2YXIgZ3JvdXBTdGFydCA9IGdyb3VwICE9PSBudWxsID8gZ3JvdXAuc3RhcnQgKiByYW5nZUZhY3RvciA6IDA7XG5cdFx0dmFyIGdyb3VwQ291bnQgPSBncm91cCAhPT0gbnVsbCA/IGdyb3VwLmNvdW50ICogcmFuZ2VGYWN0b3IgOiBJbmZpbml0eTtcblxuXHRcdHZhciBkcmF3U3RhcnQgPSBNYXRoLm1heCggcmFuZ2VTdGFydCwgZ3JvdXBTdGFydCApO1xuXHRcdHZhciBkcmF3RW5kID0gTWF0aC5taW4oIGRhdGFDb3VudCwgcmFuZ2VTdGFydCArIHJhbmdlQ291bnQsIGdyb3VwU3RhcnQgKyBncm91cENvdW50ICkgLSAxO1xuXG5cdFx0dmFyIGRyYXdDb3VudCA9IE1hdGgubWF4KCAwLCBkcmF3RW5kIC0gZHJhd1N0YXJ0ICsgMSApO1xuXG5cdFx0aWYgKCBkcmF3Q291bnQgPT09IDAgKSByZXR1cm47XG5cblx0XHQvL1xuXG5cdFx0aWYgKCBvYmplY3QuaXNNZXNoICkge1xuXG5cdFx0XHRpZiAoIG1hdGVyaWFsLndpcmVmcmFtZSA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRzdGF0ZS5zZXRMaW5lV2lkdGgoIG1hdGVyaWFsLndpcmVmcmFtZUxpbmV3aWR0aCAqIGdldFRhcmdldFBpeGVsUmF0aW8oKSApO1xuXHRcdFx0XHRyZW5kZXJlci5zZXRNb2RlKCBfZ2wuTElORVMgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRzd2l0Y2ggKCBvYmplY3QuZHJhd01vZGUgKSB7XG5cblx0XHRcdFx0XHRjYXNlIFRyaWFuZ2xlc0RyYXdNb2RlOlxuXHRcdFx0XHRcdFx0cmVuZGVyZXIuc2V0TW9kZSggX2dsLlRSSUFOR0xFUyApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIFRyaWFuZ2xlU3RyaXBEcmF3TW9kZTpcblx0XHRcdFx0XHRcdHJlbmRlcmVyLnNldE1vZGUoIF9nbC5UUklBTkdMRV9TVFJJUCApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlIFRyaWFuZ2xlRmFuRHJhd01vZGU6XG5cdFx0XHRcdFx0XHRyZW5kZXJlci5zZXRNb2RlKCBfZ2wuVFJJQU5HTEVfRkFOICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXG5cdFx0fSBlbHNlIGlmICggb2JqZWN0LmlzTGluZSApIHtcblxuXHRcdFx0dmFyIGxpbmVXaWR0aCA9IG1hdGVyaWFsLmxpbmV3aWR0aDtcblxuXHRcdFx0aWYgKCBsaW5lV2lkdGggPT09IHVuZGVmaW5lZCApIGxpbmVXaWR0aCA9IDE7IC8vIE5vdCB1c2luZyBMaW5lKk1hdGVyaWFsXG5cblx0XHRcdHN0YXRlLnNldExpbmVXaWR0aCggbGluZVdpZHRoICogZ2V0VGFyZ2V0UGl4ZWxSYXRpbygpICk7XG5cblx0XHRcdGlmICggb2JqZWN0LmlzTGluZVNlZ21lbnRzICkge1xuXG5cdFx0XHRcdHJlbmRlcmVyLnNldE1vZGUoIF9nbC5MSU5FUyApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBvYmplY3QuaXNMaW5lTG9vcCApIHtcblxuXHRcdFx0XHRyZW5kZXJlci5zZXRNb2RlKCBfZ2wuTElORV9MT09QICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0cmVuZGVyZXIuc2V0TW9kZSggX2dsLkxJTkVfU1RSSVAgKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggb2JqZWN0LmlzUG9pbnRzICkge1xuXG5cdFx0XHRyZW5kZXJlci5zZXRNb2RlKCBfZ2wuUE9JTlRTICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIGdlb21ldHJ5ICYmIGdlb21ldHJ5LmlzSW5zdGFuY2VkQnVmZmVyR2VvbWV0cnkgKSB7XG5cblx0XHRcdGlmICggZ2VvbWV0cnkubWF4SW5zdGFuY2VkQ291bnQgPiAwICkge1xuXG5cdFx0XHRcdHJlbmRlcmVyLnJlbmRlckluc3RhbmNlcyggZ2VvbWV0cnksIGRyYXdTdGFydCwgZHJhd0NvdW50ICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHJlbmRlcmVyLnJlbmRlciggZHJhd1N0YXJ0LCBkcmF3Q291bnQgKTtcblxuXHRcdH1cblxuXHR9O1xuXG5cdGZ1bmN0aW9uIHNldHVwVmVydGV4QXR0cmlidXRlcyggbWF0ZXJpYWwsIHByb2dyYW0sIGdlb21ldHJ5LCBzdGFydEluZGV4ICkge1xuXG5cdFx0aWYgKCBnZW9tZXRyeSAmJiBnZW9tZXRyeS5pc0luc3RhbmNlZEJ1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHRpZiAoIGV4dGVuc2lvbnMuZ2V0KCAnQU5HTEVfaW5zdGFuY2VkX2FycmF5cycgKSA9PT0gbnVsbCApIHtcblxuXHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xSZW5kZXJlci5zZXR1cFZlcnRleEF0dHJpYnV0ZXM6IHVzaW5nIFRIUkVFLkluc3RhbmNlZEJ1ZmZlckdlb21ldHJ5IGJ1dCBoYXJkd2FyZSBkb2VzIG5vdCBzdXBwb3J0IGV4dGVuc2lvbiBBTkdMRV9pbnN0YW5jZWRfYXJyYXlzLicgKTtcblx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHN0YXJ0SW5kZXggPT09IHVuZGVmaW5lZCApIHN0YXJ0SW5kZXggPSAwO1xuXG5cdFx0c3RhdGUuaW5pdEF0dHJpYnV0ZXMoKTtcblxuXHRcdHZhciBnZW9tZXRyeUF0dHJpYnV0ZXMgPSBnZW9tZXRyeS5hdHRyaWJ1dGVzO1xuXG5cdFx0dmFyIHByb2dyYW1BdHRyaWJ1dGVzID0gcHJvZ3JhbS5nZXRBdHRyaWJ1dGVzKCk7XG5cblx0XHR2YXIgbWF0ZXJpYWxEZWZhdWx0QXR0cmlidXRlVmFsdWVzID0gbWF0ZXJpYWwuZGVmYXVsdEF0dHJpYnV0ZVZhbHVlcztcblxuXHRcdGZvciAoIHZhciBuYW1lIGluIHByb2dyYW1BdHRyaWJ1dGVzICkge1xuXG5cdFx0XHR2YXIgcHJvZ3JhbUF0dHJpYnV0ZSA9IHByb2dyYW1BdHRyaWJ1dGVzWyBuYW1lIF07XG5cblx0XHRcdGlmICggcHJvZ3JhbUF0dHJpYnV0ZSA+PSAwICkge1xuXG5cdFx0XHRcdHZhciBnZW9tZXRyeUF0dHJpYnV0ZSA9IGdlb21ldHJ5QXR0cmlidXRlc1sgbmFtZSBdO1xuXG5cdFx0XHRcdGlmICggZ2VvbWV0cnlBdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdHZhciBub3JtYWxpemVkID0gZ2VvbWV0cnlBdHRyaWJ1dGUubm9ybWFsaXplZDtcblx0XHRcdFx0XHR2YXIgc2l6ZSA9IGdlb21ldHJ5QXR0cmlidXRlLml0ZW1TaXplO1xuXG5cdFx0XHRcdFx0dmFyIGF0dHJpYnV0ZVByb3BlcnRpZXMgPSBhdHRyaWJ1dGVzLmdldCggZ2VvbWV0cnlBdHRyaWJ1dGUgKTtcblxuXHRcdFx0XHRcdHZhciBidWZmZXIgPSBhdHRyaWJ1dGVQcm9wZXJ0aWVzLmJ1ZmZlcjtcblx0XHRcdFx0XHR2YXIgdHlwZSA9IGF0dHJpYnV0ZVByb3BlcnRpZXMudHlwZTtcblx0XHRcdFx0XHR2YXIgYnl0ZXNQZXJFbGVtZW50ID0gYXR0cmlidXRlUHJvcGVydGllcy5ieXRlc1BlckVsZW1lbnQ7XG5cblx0XHRcdFx0XHRpZiAoIGdlb21ldHJ5QXR0cmlidXRlLmlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGUgKSB7XG5cblx0XHRcdFx0XHRcdHZhciBkYXRhID0gZ2VvbWV0cnlBdHRyaWJ1dGUuZGF0YTtcblx0XHRcdFx0XHRcdHZhciBzdHJpZGUgPSBkYXRhLnN0cmlkZTtcblx0XHRcdFx0XHRcdHZhciBvZmZzZXQgPSBnZW9tZXRyeUF0dHJpYnV0ZS5vZmZzZXQ7XG5cblx0XHRcdFx0XHRcdGlmICggZGF0YSAmJiBkYXRhLmlzSW5zdGFuY2VkSW50ZXJsZWF2ZWRCdWZmZXIgKSB7XG5cblx0XHRcdFx0XHRcdFx0c3RhdGUuZW5hYmxlQXR0cmlidXRlQW5kRGl2aXNvciggcHJvZ3JhbUF0dHJpYnV0ZSwgZGF0YS5tZXNoUGVyQXR0cmlidXRlICk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Z2VvbWV0cnkubWF4SW5zdGFuY2VkQ291bnQgPSBkYXRhLm1lc2hQZXJBdHRyaWJ1dGUgKiBkYXRhLmNvdW50O1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGUoIHByb2dyYW1BdHRyaWJ1dGUgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRfZ2wuYmluZEJ1ZmZlciggX2dsLkFSUkFZX0JVRkZFUiwgYnVmZmVyICk7XG5cdFx0XHRcdFx0XHRfZ2wudmVydGV4QXR0cmliUG9pbnRlciggcHJvZ3JhbUF0dHJpYnV0ZSwgc2l6ZSwgdHlwZSwgbm9ybWFsaXplZCwgc3RyaWRlICogYnl0ZXNQZXJFbGVtZW50LCAoIHN0YXJ0SW5kZXggKiBzdHJpZGUgKyBvZmZzZXQgKSAqIGJ5dGVzUGVyRWxlbWVudCApO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBnZW9tZXRyeUF0dHJpYnV0ZS5pc0luc3RhbmNlZEJ1ZmZlckF0dHJpYnV0ZSApIHtcblxuXHRcdFx0XHRcdFx0XHRzdGF0ZS5lbmFibGVBdHRyaWJ1dGVBbmREaXZpc29yKCBwcm9ncmFtQXR0cmlidXRlLCBnZW9tZXRyeUF0dHJpYnV0ZS5tZXNoUGVyQXR0cmlidXRlICk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBnZW9tZXRyeS5tYXhJbnN0YW5jZWRDb3VudCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Z2VvbWV0cnkubWF4SW5zdGFuY2VkQ291bnQgPSBnZW9tZXRyeUF0dHJpYnV0ZS5tZXNoUGVyQXR0cmlidXRlICogZ2VvbWV0cnlBdHRyaWJ1dGUuY291bnQ7XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdHN0YXRlLmVuYWJsZUF0dHJpYnV0ZSggcHJvZ3JhbUF0dHJpYnV0ZSApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdF9nbC5iaW5kQnVmZmVyKCBfZ2wuQVJSQVlfQlVGRkVSLCBidWZmZXIgKTtcblx0XHRcdFx0XHRcdF9nbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKCBwcm9ncmFtQXR0cmlidXRlLCBzaXplLCB0eXBlLCBub3JtYWxpemVkLCAwLCBzdGFydEluZGV4ICogc2l6ZSAqIGJ5dGVzUGVyRWxlbWVudCApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsRGVmYXVsdEF0dHJpYnV0ZVZhbHVlcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0dmFyIHZhbHVlID0gbWF0ZXJpYWxEZWZhdWx0QXR0cmlidXRlVmFsdWVzWyBuYW1lIF07XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdHN3aXRjaCAoIHZhbHVlLmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdFx0XHRjYXNlIDI6XG5cdFx0XHRcdFx0XHRcdFx0X2dsLnZlcnRleEF0dHJpYjJmdiggcHJvZ3JhbUF0dHJpYnV0ZSwgdmFsdWUgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIDM6XG5cdFx0XHRcdFx0XHRcdFx0X2dsLnZlcnRleEF0dHJpYjNmdiggcHJvZ3JhbUF0dHJpYnV0ZSwgdmFsdWUgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRjYXNlIDQ6XG5cdFx0XHRcdFx0XHRcdFx0X2dsLnZlcnRleEF0dHJpYjRmdiggcHJvZ3JhbUF0dHJpYnV0ZSwgdmFsdWUgKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHRcdF9nbC52ZXJ0ZXhBdHRyaWIxZnYoIHByb2dyYW1BdHRyaWJ1dGUsIHZhbHVlICk7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHN0YXRlLmRpc2FibGVVbnVzZWRBdHRyaWJ1dGVzKCk7XG5cblx0fVxuXG5cdC8vIENvbXBpbGVcblxuXHR0aGlzLmNvbXBpbGUgPSBmdW5jdGlvbiAoIHNjZW5lLCBjYW1lcmEgKSB7XG5cblx0XHRsaWdodHMgPSBbXTtcblxuXHRcdHNjZW5lLnRyYXZlcnNlKCBmdW5jdGlvbiAoIG9iamVjdCApIHtcblxuXHRcdFx0aWYgKCBvYmplY3QuaXNMaWdodCApIHtcblxuXHRcdFx0XHRsaWdodHMucHVzaCggb2JqZWN0ICk7XG5cblx0XHRcdH1cblxuXHRcdH0gKTtcblxuXHRcdHNldHVwTGlnaHRzKCBsaWdodHMsIGNhbWVyYSApO1xuXG5cdFx0c2NlbmUudHJhdmVyc2UoIGZ1bmN0aW9uICggb2JqZWN0ICkge1xuXG5cdFx0XHRpZiAoIG9iamVjdC5tYXRlcmlhbCApIHtcblxuXHRcdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG9iamVjdC5tYXRlcmlhbCApICkge1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm1hdGVyaWFsLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHRcdFx0aW5pdE1hdGVyaWFsKCBvYmplY3QubWF0ZXJpYWxbIGkgXSwgc2NlbmUuZm9nLCBvYmplY3QgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0aW5pdE1hdGVyaWFsKCBvYmplY3QubWF0ZXJpYWwsIHNjZW5lLmZvZywgb2JqZWN0ICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9ICk7XG5cblx0fTtcblxuXHQvLyBSZW5kZXJpbmdcblxuXHR0aGlzLnJlbmRlciA9IGZ1bmN0aW9uICggc2NlbmUsIGNhbWVyYSwgcmVuZGVyVGFyZ2V0LCBmb3JjZUNsZWFyICkge1xuXG5cdFx0aWYgKCBjYW1lcmEgIT09IHVuZGVmaW5lZCAmJiBjYW1lcmEuaXNDYW1lcmEgIT09IHRydWUgKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5XZWJHTFJlbmRlcmVyLnJlbmRlcjogY2FtZXJhIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBUSFJFRS5DYW1lcmEuJyApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0Ly8gcmVzZXQgY2FjaGluZyBmb3IgdGhpcyBmcmFtZVxuXG5cdFx0X2N1cnJlbnRHZW9tZXRyeVByb2dyYW0gPSAnJztcblx0XHRfY3VycmVudE1hdGVyaWFsSWQgPSAtIDE7XG5cdFx0X2N1cnJlbnRDYW1lcmEgPSBudWxsO1xuXG5cdFx0Ly8gdXBkYXRlIHNjZW5lIGdyYXBoXG5cblx0XHRpZiAoIHNjZW5lLmF1dG9VcGRhdGUgPT09IHRydWUgKSBzY2VuZS51cGRhdGVNYXRyaXhXb3JsZCgpO1xuXG5cdFx0Ly8gdXBkYXRlIGNhbWVyYSBtYXRyaWNlcyBhbmQgZnJ1c3R1bVxuXG5cdFx0Y2FtZXJhLm9uQmVmb3JlUmVuZGVyKCBfdGhpcyApO1xuXG5cdFx0aWYgKCBjYW1lcmEucGFyZW50ID09PSBudWxsICkgY2FtZXJhLnVwZGF0ZU1hdHJpeFdvcmxkKCk7XG5cblx0XHRjYW1lcmEubWF0cml4V29ybGRJbnZlcnNlLmdldEludmVyc2UoIGNhbWVyYS5tYXRyaXhXb3JsZCApO1xuXG5cdFx0X3Byb2pTY3JlZW5NYXRyaXgubXVsdGlwbHlNYXRyaWNlcyggY2FtZXJhLnByb2plY3Rpb25NYXRyaXgsIGNhbWVyYS5tYXRyaXhXb3JsZEludmVyc2UgKTtcblx0XHRfZnJ1c3R1bS5zZXRGcm9tTWF0cml4KCBfcHJvalNjcmVlbk1hdHJpeCApO1xuXG5cdFx0bGlnaHRzLmxlbmd0aCA9IDA7XG5cdFx0c3ByaXRlcy5sZW5ndGggPSAwO1xuXHRcdGxlbnNGbGFyZXMubGVuZ3RoID0gMDtcblxuXHRcdF9sb2NhbENsaXBwaW5nRW5hYmxlZCA9IHRoaXMubG9jYWxDbGlwcGluZ0VuYWJsZWQ7XG5cdFx0X2NsaXBwaW5nRW5hYmxlZCA9IF9jbGlwcGluZy5pbml0KCB0aGlzLmNsaXBwaW5nUGxhbmVzLCBfbG9jYWxDbGlwcGluZ0VuYWJsZWQsIGNhbWVyYSApO1xuXG5cdFx0Y3VycmVudFJlbmRlckxpc3QgPSByZW5kZXJMaXN0cy5nZXQoIHNjZW5lLCBjYW1lcmEgKTtcblx0XHRjdXJyZW50UmVuZGVyTGlzdC5pbml0KCk7XG5cblx0XHRwcm9qZWN0T2JqZWN0KCBzY2VuZSwgY2FtZXJhLCBfdGhpcy5zb3J0T2JqZWN0cyApO1xuXG5cdFx0Y3VycmVudFJlbmRlckxpc3QuZmluaXNoKCk7XG5cblx0XHRpZiAoIF90aGlzLnNvcnRPYmplY3RzID09PSB0cnVlICkge1xuXG5cdFx0XHRjdXJyZW50UmVuZGVyTGlzdC5zb3J0KCk7XG5cblx0XHR9XG5cblx0XHQvL1xuXG5cdFx0aWYgKCBfY2xpcHBpbmdFbmFibGVkICkgX2NsaXBwaW5nLmJlZ2luU2hhZG93cygpO1xuXG5cdFx0c2V0dXBTaGFkb3dzKCBsaWdodHMgKTtcblxuXHRcdHNoYWRvd01hcC5yZW5kZXIoIHNjZW5lLCBjYW1lcmEgKTtcblxuXHRcdHNldHVwTGlnaHRzKCBsaWdodHMsIGNhbWVyYSApO1xuXG5cdFx0aWYgKCBfY2xpcHBpbmdFbmFibGVkICkgX2NsaXBwaW5nLmVuZFNoYWRvd3MoKTtcblxuXHRcdC8vXG5cblx0XHRfaW5mb1JlbmRlci5mcmFtZSArKztcblx0XHRfaW5mb1JlbmRlci5jYWxscyA9IDA7XG5cdFx0X2luZm9SZW5kZXIudmVydGljZXMgPSAwO1xuXHRcdF9pbmZvUmVuZGVyLmZhY2VzID0gMDtcblx0XHRfaW5mb1JlbmRlci5wb2ludHMgPSAwO1xuXG5cdFx0aWYgKCByZW5kZXJUYXJnZXQgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0cmVuZGVyVGFyZ2V0ID0gbnVsbDtcblxuXHRcdH1cblxuXHRcdHRoaXMuc2V0UmVuZGVyVGFyZ2V0KCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdC8vXG5cblx0XHR2YXIgYmFja2dyb3VuZCA9IHNjZW5lLmJhY2tncm91bmQ7XG5cblx0XHRpZiAoIGJhY2tncm91bmQgPT09IG51bGwgKSB7XG5cblx0XHRcdHN0YXRlLmJ1ZmZlcnMuY29sb3Iuc2V0Q2xlYXIoIF9jbGVhckNvbG9yLnIsIF9jbGVhckNvbG9yLmcsIF9jbGVhckNvbG9yLmIsIF9jbGVhckFscGhhLCBfcHJlbXVsdGlwbGllZEFscGhhICk7XG5cblx0XHR9IGVsc2UgaWYgKCBiYWNrZ3JvdW5kICYmIGJhY2tncm91bmQuaXNDb2xvciApIHtcblxuXHRcdFx0c3RhdGUuYnVmZmVycy5jb2xvci5zZXRDbGVhciggYmFja2dyb3VuZC5yLCBiYWNrZ3JvdW5kLmcsIGJhY2tncm91bmQuYiwgMSwgX3ByZW11bHRpcGxpZWRBbHBoYSApO1xuXHRcdFx0Zm9yY2VDbGVhciA9IHRydWU7XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuYXV0b0NsZWFyIHx8IGZvcmNlQ2xlYXIgKSB7XG5cblx0XHRcdHRoaXMuY2xlYXIoIHRoaXMuYXV0b0NsZWFyQ29sb3IsIHRoaXMuYXV0b0NsZWFyRGVwdGgsIHRoaXMuYXV0b0NsZWFyU3RlbmNpbCApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBiYWNrZ3JvdW5kICYmIGJhY2tncm91bmQuaXNDdWJlVGV4dHVyZSApIHtcblxuXHRcdFx0aWYgKCBiYWNrZ3JvdW5kQm94Q2FtZXJhID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0YmFja2dyb3VuZEJveENhbWVyYSA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSgpO1xuXG5cdFx0XHRcdGJhY2tncm91bmRCb3hNZXNoID0gbmV3IE1lc2goXG5cdFx0XHRcdFx0bmV3IEJveEJ1ZmZlckdlb21ldHJ5KCA1LCA1LCA1ICksXG5cdFx0XHRcdFx0bmV3IFNoYWRlck1hdGVyaWFsKCB7XG5cdFx0XHRcdFx0XHR1bmlmb3JtczogU2hhZGVyTGliLmN1YmUudW5pZm9ybXMsXG5cdFx0XHRcdFx0XHR2ZXJ0ZXhTaGFkZXI6IFNoYWRlckxpYi5jdWJlLnZlcnRleFNoYWRlcixcblx0XHRcdFx0XHRcdGZyYWdtZW50U2hhZGVyOiBTaGFkZXJMaWIuY3ViZS5mcmFnbWVudFNoYWRlcixcblx0XHRcdFx0XHRcdHNpZGU6IEJhY2tTaWRlLFxuXHRcdFx0XHRcdFx0ZGVwdGhUZXN0OiBmYWxzZSxcblx0XHRcdFx0XHRcdGRlcHRoV3JpdGU6IGZhbHNlLFxuXHRcdFx0XHRcdFx0Zm9nOiBmYWxzZVxuXHRcdFx0XHRcdH0gKVxuXHRcdFx0XHQpO1xuXG5cdFx0XHR9XG5cblx0XHRcdGJhY2tncm91bmRCb3hDYW1lcmEucHJvamVjdGlvbk1hdHJpeC5jb3B5KCBjYW1lcmEucHJvamVjdGlvbk1hdHJpeCApO1xuXG5cdFx0XHRiYWNrZ3JvdW5kQm94Q2FtZXJhLm1hdHJpeFdvcmxkLmV4dHJhY3RSb3RhdGlvbiggY2FtZXJhLm1hdHJpeFdvcmxkICk7XG5cdFx0XHRiYWNrZ3JvdW5kQm94Q2FtZXJhLm1hdHJpeFdvcmxkSW52ZXJzZS5nZXRJbnZlcnNlKCBiYWNrZ3JvdW5kQm94Q2FtZXJhLm1hdHJpeFdvcmxkICk7XG5cblxuXHRcdFx0YmFja2dyb3VuZEJveE1lc2gubWF0ZXJpYWwudW5pZm9ybXNbIFwidEN1YmVcIiBdLnZhbHVlID0gYmFja2dyb3VuZDtcblx0XHRcdGJhY2tncm91bmRCb3hNZXNoLm1vZGVsVmlld01hdHJpeC5tdWx0aXBseU1hdHJpY2VzKCBiYWNrZ3JvdW5kQm94Q2FtZXJhLm1hdHJpeFdvcmxkSW52ZXJzZSwgYmFja2dyb3VuZEJveE1lc2gubWF0cml4V29ybGQgKTtcblxuXHRcdFx0b2JqZWN0cy51cGRhdGUoIGJhY2tncm91bmRCb3hNZXNoICk7XG5cblx0XHRcdF90aGlzLnJlbmRlckJ1ZmZlckRpcmVjdCggYmFja2dyb3VuZEJveENhbWVyYSwgbnVsbCwgYmFja2dyb3VuZEJveE1lc2guZ2VvbWV0cnksIGJhY2tncm91bmRCb3hNZXNoLm1hdGVyaWFsLCBiYWNrZ3JvdW5kQm94TWVzaCwgbnVsbCApO1xuXG5cdFx0fSBlbHNlIGlmICggYmFja2dyb3VuZCAmJiBiYWNrZ3JvdW5kLmlzVGV4dHVyZSApIHtcblxuXHRcdFx0aWYgKCBiYWNrZ3JvdW5kUGxhbmVDYW1lcmEgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRiYWNrZ3JvdW5kUGxhbmVDYW1lcmEgPSBuZXcgT3J0aG9ncmFwaGljQ2FtZXJhKCAtIDEsIDEsIDEsIC0gMSwgMCwgMSApO1xuXG5cdFx0XHRcdGJhY2tncm91bmRQbGFuZU1lc2ggPSBuZXcgTWVzaChcblx0XHRcdFx0XHRuZXcgUGxhbmVCdWZmZXJHZW9tZXRyeSggMiwgMiApLFxuXHRcdFx0XHRcdG5ldyBNZXNoQmFzaWNNYXRlcmlhbCggeyBkZXB0aFRlc3Q6IGZhbHNlLCBkZXB0aFdyaXRlOiBmYWxzZSwgZm9nOiBmYWxzZSB9IClcblx0XHRcdFx0KTtcblxuXHRcdFx0fVxuXG5cdFx0XHRiYWNrZ3JvdW5kUGxhbmVNZXNoLm1hdGVyaWFsLm1hcCA9IGJhY2tncm91bmQ7XG5cblx0XHRcdG9iamVjdHMudXBkYXRlKCBiYWNrZ3JvdW5kUGxhbmVNZXNoICk7XG5cblx0XHRcdF90aGlzLnJlbmRlckJ1ZmZlckRpcmVjdCggYmFja2dyb3VuZFBsYW5lQ2FtZXJhLCBudWxsLCBiYWNrZ3JvdW5kUGxhbmVNZXNoLmdlb21ldHJ5LCBiYWNrZ3JvdW5kUGxhbmVNZXNoLm1hdGVyaWFsLCBiYWNrZ3JvdW5kUGxhbmVNZXNoLCBudWxsICk7XG5cblx0XHR9XG5cblx0XHQvL1xuXG5cdFx0dmFyIG9wYXF1ZU9iamVjdHMgPSBjdXJyZW50UmVuZGVyTGlzdC5vcGFxdWU7XG5cdFx0dmFyIHRyYW5zcGFyZW50T2JqZWN0cyA9IGN1cnJlbnRSZW5kZXJMaXN0LnRyYW5zcGFyZW50O1xuXG5cdFx0aWYgKCBzY2VuZS5vdmVycmlkZU1hdGVyaWFsICkge1xuXG5cdFx0XHR2YXIgb3ZlcnJpZGVNYXRlcmlhbCA9IHNjZW5lLm92ZXJyaWRlTWF0ZXJpYWw7XG5cblx0XHRcdGlmICggb3BhcXVlT2JqZWN0cy5sZW5ndGggKSByZW5kZXJPYmplY3RzKCBvcGFxdWVPYmplY3RzLCBzY2VuZSwgY2FtZXJhLCBvdmVycmlkZU1hdGVyaWFsICk7XG5cdFx0XHRpZiAoIHRyYW5zcGFyZW50T2JqZWN0cy5sZW5ndGggKSByZW5kZXJPYmplY3RzKCB0cmFuc3BhcmVudE9iamVjdHMsIHNjZW5lLCBjYW1lcmEsIG92ZXJyaWRlTWF0ZXJpYWwgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIG9wYXF1ZSBwYXNzIChmcm9udC10by1iYWNrIG9yZGVyKVxuXG5cdFx0XHRpZiAoIG9wYXF1ZU9iamVjdHMubGVuZ3RoICkgcmVuZGVyT2JqZWN0cyggb3BhcXVlT2JqZWN0cywgc2NlbmUsIGNhbWVyYSApO1xuXG5cdFx0XHQvLyB0cmFuc3BhcmVudCBwYXNzIChiYWNrLXRvLWZyb250IG9yZGVyKVxuXG5cdFx0XHRpZiAoIHRyYW5zcGFyZW50T2JqZWN0cy5sZW5ndGggKSByZW5kZXJPYmplY3RzKCB0cmFuc3BhcmVudE9iamVjdHMsIHNjZW5lLCBjYW1lcmEgKTtcblxuXHRcdH1cblxuXHRcdC8vIGN1c3RvbSByZW5kZXIgcGx1Z2lucyAocG9zdCBwYXNzKVxuXG5cdFx0c3ByaXRlUGx1Z2luLnJlbmRlciggc2NlbmUsIGNhbWVyYSApO1xuXHRcdGxlbnNGbGFyZVBsdWdpbi5yZW5kZXIoIHNjZW5lLCBjYW1lcmEsIF9jdXJyZW50Vmlld3BvcnQgKTtcblxuXHRcdC8vIEdlbmVyYXRlIG1pcG1hcCBpZiB3ZSdyZSB1c2luZyBhbnkga2luZCBvZiBtaXBtYXAgZmlsdGVyaW5nXG5cblx0XHRpZiAoIHJlbmRlclRhcmdldCApIHtcblxuXHRcdFx0dGV4dHVyZXMudXBkYXRlUmVuZGVyVGFyZ2V0TWlwbWFwKCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSBkZXB0aCBidWZmZXIgd3JpdGluZyBpcyBlbmFibGVkIHNvIGl0IGNhbiBiZSBjbGVhcmVkIG9uIG5leHQgcmVuZGVyXG5cblx0XHRzdGF0ZS5idWZmZXJzLmRlcHRoLnNldFRlc3QoIHRydWUgKTtcblx0XHRzdGF0ZS5idWZmZXJzLmRlcHRoLnNldE1hc2soIHRydWUgKTtcblx0XHRzdGF0ZS5idWZmZXJzLmNvbG9yLnNldE1hc2soIHRydWUgKTtcblxuXHRcdGlmICggY2FtZXJhLmlzQXJyYXlDYW1lcmEgJiYgY2FtZXJhLmVuYWJsZWQgKSB7XG5cblx0XHRcdF90aGlzLnNldFNjaXNzb3JUZXN0KCBmYWxzZSApO1xuXG5cdFx0fVxuXG5cdFx0Y2FtZXJhLm9uQWZ0ZXJSZW5kZXIoIF90aGlzICk7XG5cblx0XHQvLyBfZ2wuZmluaXNoKCk7XG5cblx0fTtcblxuXHQvKlxuXHQvLyBUT0RPIER1cGxpY2F0ZWQgY29kZSAoRnJ1c3R1bSlcblxuXHR2YXIgX3NwaGVyZSA9IG5ldyBTcGhlcmUoKTtcblxuXHRmdW5jdGlvbiBpc09iamVjdFZpZXdhYmxlKCBvYmplY3QgKSB7XG5cblx0XHR2YXIgZ2VvbWV0cnkgPSBvYmplY3QuZ2VvbWV0cnk7XG5cblx0XHRpZiAoIGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlID09PSBudWxsIClcblx0XHRcdGdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpO1xuXG5cdFx0X3NwaGVyZS5jb3B5KCBnZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSApLlxuXHRcdGFwcGx5TWF0cml4NCggb2JqZWN0Lm1hdHJpeFdvcmxkICk7XG5cblx0XHRyZXR1cm4gaXNTcGhlcmVWaWV3YWJsZSggX3NwaGVyZSApO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBpc1Nwcml0ZVZpZXdhYmxlKCBzcHJpdGUgKSB7XG5cblx0XHRfc3BoZXJlLmNlbnRlci5zZXQoIDAsIDAsIDAgKTtcblx0XHRfc3BoZXJlLnJhZGl1cyA9IDAuNzA3MTA2NzgxMTg2NTQ3Njtcblx0XHRfc3BoZXJlLmFwcGx5TWF0cml4NCggc3ByaXRlLm1hdHJpeFdvcmxkICk7XG5cblx0XHRyZXR1cm4gaXNTcGhlcmVWaWV3YWJsZSggX3NwaGVyZSApO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBpc1NwaGVyZVZpZXdhYmxlKCBzcGhlcmUgKSB7XG5cblx0XHRpZiAoICEgX2ZydXN0dW0uaW50ZXJzZWN0c1NwaGVyZSggc3BoZXJlICkgKSByZXR1cm4gZmFsc2U7XG5cblx0XHR2YXIgbnVtUGxhbmVzID0gX2NsaXBwaW5nLm51bVBsYW5lcztcblxuXHRcdGlmICggbnVtUGxhbmVzID09PSAwICkgcmV0dXJuIHRydWU7XG5cblx0XHR2YXIgcGxhbmVzID0gX3RoaXMuY2xpcHBpbmdQbGFuZXMsXG5cblx0XHRcdGNlbnRlciA9IHNwaGVyZS5jZW50ZXIsXG5cdFx0XHRuZWdSYWQgPSAtIHNwaGVyZS5yYWRpdXMsXG5cdFx0XHRpID0gMDtcblxuXHRcdGRvIHtcblxuXHRcdFx0Ly8gb3V0IHdoZW4gZGVlcGVyIHRoYW4gcmFkaXVzIGluIHRoZSBuZWdhdGl2ZSBoYWxmc3BhY2Vcblx0XHRcdGlmICggcGxhbmVzWyBpIF0uZGlzdGFuY2VUb1BvaW50KCBjZW50ZXIgKSA8IG5lZ1JhZCApIHJldHVybiBmYWxzZTtcblxuXHRcdH0gd2hpbGUgKCArKyBpICE9PSBudW1QbGFuZXMgKTtcblxuXHRcdHJldHVybiB0cnVlO1xuXG5cdH1cblx0Ki9cblxuXHRmdW5jdGlvbiBwcm9qZWN0T2JqZWN0KCBvYmplY3QsIGNhbWVyYSwgc29ydE9iamVjdHMgKSB7XG5cblx0XHRpZiAoICEgb2JqZWN0LnZpc2libGUgKSByZXR1cm47XG5cblx0XHR2YXIgdmlzaWJsZSA9IG9iamVjdC5sYXllcnMudGVzdCggY2FtZXJhLmxheWVycyApO1xuXG5cdFx0aWYgKCB2aXNpYmxlICkge1xuXG5cdFx0XHRpZiAoIG9iamVjdC5pc0xpZ2h0ICkge1xuXG5cdFx0XHRcdGxpZ2h0cy5wdXNoKCBvYmplY3QgKTtcblxuXHRcdFx0fSBlbHNlIGlmICggb2JqZWN0LmlzU3ByaXRlICkge1xuXG5cdFx0XHRcdGlmICggISBvYmplY3QuZnJ1c3R1bUN1bGxlZCB8fCBfZnJ1c3R1bS5pbnRlcnNlY3RzU3ByaXRlKCBvYmplY3QgKSApIHtcblxuXHRcdFx0XHRcdHNwcml0ZXMucHVzaCggb2JqZWN0ICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKCBvYmplY3QuaXNMZW5zRmxhcmUgKSB7XG5cblx0XHRcdFx0bGVuc0ZsYXJlcy5wdXNoKCBvYmplY3QgKTtcblxuXHRcdFx0fSBlbHNlIGlmICggb2JqZWN0LmlzSW1tZWRpYXRlUmVuZGVyT2JqZWN0ICkge1xuXG5cdFx0XHRcdGlmICggc29ydE9iamVjdHMgKSB7XG5cblx0XHRcdFx0XHRfdmVjdG9yMy5zZXRGcm9tTWF0cml4UG9zaXRpb24oIG9iamVjdC5tYXRyaXhXb3JsZCApXG5cdFx0XHRcdFx0XHQuYXBwbHlNYXRyaXg0KCBfcHJvalNjcmVlbk1hdHJpeCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjdXJyZW50UmVuZGVyTGlzdC5wdXNoKCBvYmplY3QsIG51bGwsIG9iamVjdC5tYXRlcmlhbCwgX3ZlY3RvcjMueiwgbnVsbCApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBvYmplY3QuaXNNZXNoIHx8IG9iamVjdC5pc0xpbmUgfHwgb2JqZWN0LmlzUG9pbnRzICkge1xuXG5cdFx0XHRcdGlmICggb2JqZWN0LmlzU2tpbm5lZE1lc2ggKSB7XG5cblx0XHRcdFx0XHRvYmplY3Quc2tlbGV0b24udXBkYXRlKCk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggISBvYmplY3QuZnJ1c3R1bUN1bGxlZCB8fCBfZnJ1c3R1bS5pbnRlcnNlY3RzT2JqZWN0KCBvYmplY3QgKSApIHtcblxuXHRcdFx0XHRcdGlmICggc29ydE9iamVjdHMgKSB7XG5cblx0XHRcdFx0XHRcdF92ZWN0b3IzLnNldEZyb21NYXRyaXhQb3NpdGlvbiggb2JqZWN0Lm1hdHJpeFdvcmxkIClcblx0XHRcdFx0XHRcdFx0LmFwcGx5TWF0cml4NCggX3Byb2pTY3JlZW5NYXRyaXggKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHZhciBnZW9tZXRyeSA9IG9iamVjdHMudXBkYXRlKCBvYmplY3QgKTtcblx0XHRcdFx0XHR2YXIgbWF0ZXJpYWwgPSBvYmplY3QubWF0ZXJpYWw7XG5cblx0XHRcdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG1hdGVyaWFsICkgKSB7XG5cblx0XHRcdFx0XHRcdHZhciBncm91cHMgPSBnZW9tZXRyeS5ncm91cHM7XG5cblx0XHRcdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGdyb3Vwcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdHZhciBncm91cCA9IGdyb3Vwc1sgaSBdO1xuXHRcdFx0XHRcdFx0XHR2YXIgZ3JvdXBNYXRlcmlhbCA9IG1hdGVyaWFsWyBncm91cC5tYXRlcmlhbEluZGV4IF07XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBncm91cE1hdGVyaWFsICYmIGdyb3VwTWF0ZXJpYWwudmlzaWJsZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRSZW5kZXJMaXN0LnB1c2goIG9iamVjdCwgZ2VvbWV0cnksIGdyb3VwTWF0ZXJpYWwsIF92ZWN0b3IzLnosIGdyb3VwICk7XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC52aXNpYmxlICkge1xuXG5cdFx0XHRcdFx0XHRjdXJyZW50UmVuZGVyTGlzdC5wdXNoKCBvYmplY3QsIGdlb21ldHJ5LCBtYXRlcmlhbCwgX3ZlY3RvcjMueiwgbnVsbCApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIGNoaWxkcmVuID0gb2JqZWN0LmNoaWxkcmVuO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0cHJvamVjdE9iamVjdCggY2hpbGRyZW5bIGkgXSwgY2FtZXJhLCBzb3J0T2JqZWN0cyApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiByZW5kZXJPYmplY3RzKCByZW5kZXJMaXN0LCBzY2VuZSwgY2FtZXJhLCBvdmVycmlkZU1hdGVyaWFsICkge1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gcmVuZGVyTGlzdC5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgcmVuZGVySXRlbSA9IHJlbmRlckxpc3RbIGkgXTtcblxuXHRcdFx0dmFyIG9iamVjdCA9IHJlbmRlckl0ZW0ub2JqZWN0O1xuXHRcdFx0dmFyIGdlb21ldHJ5ID0gcmVuZGVySXRlbS5nZW9tZXRyeTtcblx0XHRcdHZhciBtYXRlcmlhbCA9IG92ZXJyaWRlTWF0ZXJpYWwgPT09IHVuZGVmaW5lZCA/IHJlbmRlckl0ZW0ubWF0ZXJpYWwgOiBvdmVycmlkZU1hdGVyaWFsO1xuXHRcdFx0dmFyIGdyb3VwID0gcmVuZGVySXRlbS5ncm91cDtcblxuXHRcdFx0b2JqZWN0Lm9uQmVmb3JlUmVuZGVyKCBfdGhpcywgc2NlbmUsIGNhbWVyYSwgZ2VvbWV0cnksIG1hdGVyaWFsLCBncm91cCApO1xuXG5cdFx0XHRpZiAoIGNhbWVyYS5pc0FycmF5Q2FtZXJhICYmIGNhbWVyYS5lbmFibGVkICkge1xuXG5cdFx0XHRcdHZhciBjYW1lcmFzID0gY2FtZXJhLmNhbWVyYXM7XG5cblx0XHRcdFx0Zm9yICggdmFyIGogPSAwLCBqbCA9IGNhbWVyYXMubGVuZ3RoOyBqIDwgamw7IGogKysgKSB7XG5cblx0XHRcdFx0XHR2YXIgY2FtZXJhMiA9IGNhbWVyYXNbIGogXTtcblx0XHRcdFx0XHR2YXIgYm91bmRzID0gY2FtZXJhMi5ib3VuZHM7XG5cblx0XHRcdFx0XHRfdGhpcy5zZXRWaWV3cG9ydChcblx0XHRcdFx0XHRcdGJvdW5kcy54ICogX3dpZHRoICogX3BpeGVsUmF0aW8sIGJvdW5kcy55ICogX2hlaWdodCAqIF9waXhlbFJhdGlvLFxuXHRcdFx0XHRcdFx0Ym91bmRzLnogKiBfd2lkdGggKiBfcGl4ZWxSYXRpbywgYm91bmRzLncgKiBfaGVpZ2h0ICogX3BpeGVsUmF0aW9cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdF90aGlzLnNldFNjaXNzb3IoXG5cdFx0XHRcdFx0XHRib3VuZHMueCAqIF93aWR0aCAqIF9waXhlbFJhdGlvLCBib3VuZHMueSAqIF9oZWlnaHQgKiBfcGl4ZWxSYXRpbyxcblx0XHRcdFx0XHRcdGJvdW5kcy56ICogX3dpZHRoICogX3BpeGVsUmF0aW8sIGJvdW5kcy53ICogX2hlaWdodCAqIF9waXhlbFJhdGlvXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRfdGhpcy5zZXRTY2lzc29yVGVzdCggdHJ1ZSApO1xuXG5cdFx0XHRcdFx0cmVuZGVyT2JqZWN0KCBvYmplY3QsIHNjZW5lLCBjYW1lcmEyLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIGdyb3VwICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHJlbmRlck9iamVjdCggb2JqZWN0LCBzY2VuZSwgY2FtZXJhLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIGdyb3VwICk7XG5cblx0XHRcdH1cblxuXHRcdFx0b2JqZWN0Lm9uQWZ0ZXJSZW5kZXIoIF90aGlzLCBzY2VuZSwgY2FtZXJhLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIGdyb3VwICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIHJlbmRlck9iamVjdCggb2JqZWN0LCBzY2VuZSwgY2FtZXJhLCBnZW9tZXRyeSwgbWF0ZXJpYWwsIGdyb3VwICkge1xuXG5cdFx0b2JqZWN0Lm1vZGVsVmlld01hdHJpeC5tdWx0aXBseU1hdHJpY2VzKCBjYW1lcmEubWF0cml4V29ybGRJbnZlcnNlLCBvYmplY3QubWF0cml4V29ybGQgKTtcblx0XHRvYmplY3Qubm9ybWFsTWF0cml4LmdldE5vcm1hbE1hdHJpeCggb2JqZWN0Lm1vZGVsVmlld01hdHJpeCApO1xuXG5cdFx0aWYgKCBvYmplY3QuaXNJbW1lZGlhdGVSZW5kZXJPYmplY3QgKSB7XG5cblx0XHRcdHN0YXRlLnNldE1hdGVyaWFsKCBtYXRlcmlhbCApO1xuXG5cdFx0XHR2YXIgcHJvZ3JhbSA9IHNldFByb2dyYW0oIGNhbWVyYSwgc2NlbmUuZm9nLCBtYXRlcmlhbCwgb2JqZWN0ICk7XG5cblx0XHRcdF9jdXJyZW50R2VvbWV0cnlQcm9ncmFtID0gJyc7XG5cblx0XHRcdHJlbmRlck9iamVjdEltbWVkaWF0ZSggb2JqZWN0LCBwcm9ncmFtLCBtYXRlcmlhbCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0X3RoaXMucmVuZGVyQnVmZmVyRGlyZWN0KCBjYW1lcmEsIHNjZW5lLmZvZywgZ2VvbWV0cnksIG1hdGVyaWFsLCBvYmplY3QsIGdyb3VwICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGluaXRNYXRlcmlhbCggbWF0ZXJpYWwsIGZvZywgb2JqZWN0ICkge1xuXG5cdFx0dmFyIG1hdGVyaWFsUHJvcGVydGllcyA9IHByb3BlcnRpZXMuZ2V0KCBtYXRlcmlhbCApO1xuXG5cdFx0dmFyIHBhcmFtZXRlcnMgPSBwcm9ncmFtQ2FjaGUuZ2V0UGFyYW1ldGVycyhcblx0XHRcdG1hdGVyaWFsLCBfbGlnaHRzLCBmb2csIF9jbGlwcGluZy5udW1QbGFuZXMsIF9jbGlwcGluZy5udW1JbnRlcnNlY3Rpb24sIG9iamVjdCApO1xuXG5cdFx0dmFyIGNvZGUgPSBwcm9ncmFtQ2FjaGUuZ2V0UHJvZ3JhbUNvZGUoIG1hdGVyaWFsLCBwYXJhbWV0ZXJzICk7XG5cblx0XHR2YXIgcHJvZ3JhbSA9IG1hdGVyaWFsUHJvcGVydGllcy5wcm9ncmFtO1xuXHRcdHZhciBwcm9ncmFtQ2hhbmdlID0gdHJ1ZTtcblxuXHRcdGlmICggcHJvZ3JhbSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHQvLyBuZXcgbWF0ZXJpYWxcblx0XHRcdG1hdGVyaWFsLmFkZEV2ZW50TGlzdGVuZXIoICdkaXNwb3NlJywgb25NYXRlcmlhbERpc3Bvc2UgKTtcblxuXHRcdH0gZWxzZSBpZiAoIHByb2dyYW0uY29kZSAhPT0gY29kZSApIHtcblxuXHRcdFx0Ly8gY2hhbmdlZCBnbHNsIG9yIHBhcmFtZXRlcnNcblx0XHRcdHJlbGVhc2VNYXRlcmlhbFByb2dyYW1SZWZlcmVuY2UoIG1hdGVyaWFsICk7XG5cblx0XHR9IGVsc2UgaWYgKCBwYXJhbWV0ZXJzLnNoYWRlcklEICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIHNhbWUgZ2xzbCBhbmQgdW5pZm9ybSBsaXN0XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBvbmx5IHJlYnVpbGQgdW5pZm9ybSBsaXN0XG5cdFx0XHRwcm9ncmFtQ2hhbmdlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHRpZiAoIHByb2dyYW1DaGFuZ2UgKSB7XG5cblx0XHRcdGlmICggcGFyYW1ldGVycy5zaGFkZXJJRCApIHtcblxuXHRcdFx0XHR2YXIgc2hhZGVyID0gU2hhZGVyTGliWyBwYXJhbWV0ZXJzLnNoYWRlcklEIF07XG5cblx0XHRcdFx0bWF0ZXJpYWxQcm9wZXJ0aWVzLl9fd2ViZ2xTaGFkZXIgPSB7XG5cdFx0XHRcdFx0bmFtZTogbWF0ZXJpYWwudHlwZSxcblx0XHRcdFx0XHR1bmlmb3JtczogVW5pZm9ybXNVdGlscy5jbG9uZSggc2hhZGVyLnVuaWZvcm1zICksXG5cdFx0XHRcdFx0dmVydGV4U2hhZGVyOiBzaGFkZXIudmVydGV4U2hhZGVyLFxuXHRcdFx0XHRcdGZyYWdtZW50U2hhZGVyOiBzaGFkZXIuZnJhZ21lbnRTaGFkZXJcblx0XHRcdFx0fTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRtYXRlcmlhbFByb3BlcnRpZXMuX193ZWJnbFNoYWRlciA9IHtcblx0XHRcdFx0XHRuYW1lOiBtYXRlcmlhbC50eXBlLFxuXHRcdFx0XHRcdHVuaWZvcm1zOiBtYXRlcmlhbC51bmlmb3Jtcyxcblx0XHRcdFx0XHR2ZXJ0ZXhTaGFkZXI6IG1hdGVyaWFsLnZlcnRleFNoYWRlcixcblx0XHRcdFx0XHRmcmFnbWVudFNoYWRlcjogbWF0ZXJpYWwuZnJhZ21lbnRTaGFkZXJcblx0XHRcdFx0fTtcblxuXHRcdFx0fVxuXG5cdFx0XHRtYXRlcmlhbC5fX3dlYmdsU2hhZGVyID0gbWF0ZXJpYWxQcm9wZXJ0aWVzLl9fd2ViZ2xTaGFkZXI7XG5cblx0XHRcdHByb2dyYW0gPSBwcm9ncmFtQ2FjaGUuYWNxdWlyZVByb2dyYW0oIG1hdGVyaWFsLCBwYXJhbWV0ZXJzLCBjb2RlICk7XG5cblx0XHRcdG1hdGVyaWFsUHJvcGVydGllcy5wcm9ncmFtID0gcHJvZ3JhbTtcblx0XHRcdG1hdGVyaWFsLnByb2dyYW0gPSBwcm9ncmFtO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHByb2dyYW1BdHRyaWJ1dGVzID0gcHJvZ3JhbS5nZXRBdHRyaWJ1dGVzKCk7XG5cblx0XHRpZiAoIG1hdGVyaWFsLm1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0bWF0ZXJpYWwubnVtU3VwcG9ydGVkTW9ycGhUYXJnZXRzID0gMDtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgX3RoaXMubWF4TW9ycGhUYXJnZXRzOyBpICsrICkge1xuXG5cdFx0XHRcdGlmICggcHJvZ3JhbUF0dHJpYnV0ZXNbICdtb3JwaFRhcmdldCcgKyBpIF0gPj0gMCApIHtcblxuXHRcdFx0XHRcdG1hdGVyaWFsLm51bVN1cHBvcnRlZE1vcnBoVGFyZ2V0cyArKztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggbWF0ZXJpYWwubW9ycGhOb3JtYWxzICkge1xuXG5cdFx0XHRtYXRlcmlhbC5udW1TdXBwb3J0ZWRNb3JwaE5vcm1hbHMgPSAwO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBfdGhpcy5tYXhNb3JwaE5vcm1hbHM7IGkgKysgKSB7XG5cblx0XHRcdFx0aWYgKCBwcm9ncmFtQXR0cmlidXRlc1sgJ21vcnBoTm9ybWFsJyArIGkgXSA+PSAwICkge1xuXG5cdFx0XHRcdFx0bWF0ZXJpYWwubnVtU3VwcG9ydGVkTW9ycGhOb3JtYWxzICsrO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIHVuaWZvcm1zID0gbWF0ZXJpYWxQcm9wZXJ0aWVzLl9fd2ViZ2xTaGFkZXIudW5pZm9ybXM7XG5cblx0XHRpZiAoICEgbWF0ZXJpYWwuaXNTaGFkZXJNYXRlcmlhbCAmJlxuXHRcdFx0ISBtYXRlcmlhbC5pc1Jhd1NoYWRlck1hdGVyaWFsIHx8XG5cdFx0XHRtYXRlcmlhbC5jbGlwcGluZyA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0bWF0ZXJpYWxQcm9wZXJ0aWVzLm51bUNsaXBwaW5nUGxhbmVzID0gX2NsaXBwaW5nLm51bVBsYW5lcztcblx0XHRcdG1hdGVyaWFsUHJvcGVydGllcy5udW1JbnRlcnNlY3Rpb24gPSBfY2xpcHBpbmcubnVtSW50ZXJzZWN0aW9uO1xuXHRcdFx0dW5pZm9ybXMuY2xpcHBpbmdQbGFuZXMgPSBfY2xpcHBpbmcudW5pZm9ybTtcblxuXHRcdH1cblxuXHRcdG1hdGVyaWFsUHJvcGVydGllcy5mb2cgPSBmb2c7XG5cblx0XHQvLyBzdG9yZSB0aGUgbGlnaHQgc2V0dXAgaXQgd2FzIGNyZWF0ZWQgZm9yXG5cblx0XHRtYXRlcmlhbFByb3BlcnRpZXMubGlnaHRzSGFzaCA9IF9saWdodHMuaGFzaDtcblxuXHRcdGlmICggbWF0ZXJpYWwubGlnaHRzICkge1xuXG5cdFx0XHQvLyB3aXJlIHVwIHRoZSBtYXRlcmlhbCB0byB0aGlzIHJlbmRlcmVyJ3MgbGlnaHRpbmcgc3RhdGVcblxuXHRcdFx0dW5pZm9ybXMuYW1iaWVudExpZ2h0Q29sb3IudmFsdWUgPSBfbGlnaHRzLmFtYmllbnQ7XG5cdFx0XHR1bmlmb3Jtcy5kaXJlY3Rpb25hbExpZ2h0cy52YWx1ZSA9IF9saWdodHMuZGlyZWN0aW9uYWw7XG5cdFx0XHR1bmlmb3Jtcy5zcG90TGlnaHRzLnZhbHVlID0gX2xpZ2h0cy5zcG90O1xuXHRcdFx0dW5pZm9ybXMucmVjdEFyZWFMaWdodHMudmFsdWUgPSBfbGlnaHRzLnJlY3RBcmVhO1xuXHRcdFx0dW5pZm9ybXMucG9pbnRMaWdodHMudmFsdWUgPSBfbGlnaHRzLnBvaW50O1xuXHRcdFx0dW5pZm9ybXMuaGVtaXNwaGVyZUxpZ2h0cy52YWx1ZSA9IF9saWdodHMuaGVtaTtcblxuXHRcdFx0dW5pZm9ybXMuZGlyZWN0aW9uYWxTaGFkb3dNYXAudmFsdWUgPSBfbGlnaHRzLmRpcmVjdGlvbmFsU2hhZG93TWFwO1xuXHRcdFx0dW5pZm9ybXMuZGlyZWN0aW9uYWxTaGFkb3dNYXRyaXgudmFsdWUgPSBfbGlnaHRzLmRpcmVjdGlvbmFsU2hhZG93TWF0cml4O1xuXHRcdFx0dW5pZm9ybXMuc3BvdFNoYWRvd01hcC52YWx1ZSA9IF9saWdodHMuc3BvdFNoYWRvd01hcDtcblx0XHRcdHVuaWZvcm1zLnNwb3RTaGFkb3dNYXRyaXgudmFsdWUgPSBfbGlnaHRzLnNwb3RTaGFkb3dNYXRyaXg7XG5cdFx0XHR1bmlmb3Jtcy5wb2ludFNoYWRvd01hcC52YWx1ZSA9IF9saWdodHMucG9pbnRTaGFkb3dNYXA7XG5cdFx0XHR1bmlmb3Jtcy5wb2ludFNoYWRvd01hdHJpeC52YWx1ZSA9IF9saWdodHMucG9pbnRTaGFkb3dNYXRyaXg7XG5cdFx0XHQvLyBUT0RPIChhYmVsbmF0aW9uKTogYWRkIGFyZWEgbGlnaHRzIHNoYWRvdyBpbmZvIHRvIHVuaWZvcm1zXG5cblx0XHR9XG5cblx0XHR2YXIgcHJvZ1VuaWZvcm1zID0gbWF0ZXJpYWxQcm9wZXJ0aWVzLnByb2dyYW0uZ2V0VW5pZm9ybXMoKSxcblx0XHRcdHVuaWZvcm1zTGlzdCA9XG5cdFx0XHRcdFdlYkdMVW5pZm9ybXMuc2VxV2l0aFZhbHVlKCBwcm9nVW5pZm9ybXMuc2VxLCB1bmlmb3JtcyApO1xuXG5cdFx0bWF0ZXJpYWxQcm9wZXJ0aWVzLnVuaWZvcm1zTGlzdCA9IHVuaWZvcm1zTGlzdDtcblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0UHJvZ3JhbSggY2FtZXJhLCBmb2csIG1hdGVyaWFsLCBvYmplY3QgKSB7XG5cblx0XHRfdXNlZFRleHR1cmVVbml0cyA9IDA7XG5cblx0XHR2YXIgbWF0ZXJpYWxQcm9wZXJ0aWVzID0gcHJvcGVydGllcy5nZXQoIG1hdGVyaWFsICk7XG5cblx0XHRpZiAoIF9jbGlwcGluZ0VuYWJsZWQgKSB7XG5cblx0XHRcdGlmICggX2xvY2FsQ2xpcHBpbmdFbmFibGVkIHx8IGNhbWVyYSAhPT0gX2N1cnJlbnRDYW1lcmEgKSB7XG5cblx0XHRcdFx0dmFyIHVzZUNhY2hlID1cblx0XHRcdFx0XHRjYW1lcmEgPT09IF9jdXJyZW50Q2FtZXJhICYmXG5cdFx0XHRcdFx0bWF0ZXJpYWwuaWQgPT09IF9jdXJyZW50TWF0ZXJpYWxJZDtcblxuXHRcdFx0XHQvLyB3ZSBtaWdodCB3YW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiB3aXRoIHNvbWUgQ2xpcHBpbmdHcm91cFxuXHRcdFx0XHQvLyBvYmplY3QgaW5zdGVhZCBvZiB0aGUgbWF0ZXJpYWwsIG9uY2UgaXQgYmVjb21lcyBmZWFzaWJsZVxuXHRcdFx0XHQvLyAoIzg0NjUsICM4Mzc5KVxuXHRcdFx0XHRfY2xpcHBpbmcuc2V0U3RhdGUoXG5cdFx0XHRcdFx0bWF0ZXJpYWwuY2xpcHBpbmdQbGFuZXMsIG1hdGVyaWFsLmNsaXBJbnRlcnNlY3Rpb24sIG1hdGVyaWFsLmNsaXBTaGFkb3dzLFxuXHRcdFx0XHRcdGNhbWVyYSwgbWF0ZXJpYWxQcm9wZXJ0aWVzLCB1c2VDYWNoZSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIG1hdGVyaWFsLm5lZWRzVXBkYXRlID09PSBmYWxzZSApIHtcblxuXHRcdFx0aWYgKCBtYXRlcmlhbFByb3BlcnRpZXMucHJvZ3JhbSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwuZm9nICYmIG1hdGVyaWFsUHJvcGVydGllcy5mb2cgIT09IGZvZyApIHtcblxuXHRcdFx0XHRtYXRlcmlhbC5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmxpZ2h0cyAmJiBtYXRlcmlhbFByb3BlcnRpZXMubGlnaHRzSGFzaCAhPT0gX2xpZ2h0cy5oYXNoICkge1xuXG5cdFx0XHRcdG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fSBlbHNlIGlmICggbWF0ZXJpYWxQcm9wZXJ0aWVzLm51bUNsaXBwaW5nUGxhbmVzICE9PSB1bmRlZmluZWQgJiZcblx0XHRcdFx0KCBtYXRlcmlhbFByb3BlcnRpZXMubnVtQ2xpcHBpbmdQbGFuZXMgIT09IF9jbGlwcGluZy5udW1QbGFuZXMgfHxcblx0XHRcdFx0bWF0ZXJpYWxQcm9wZXJ0aWVzLm51bUludGVyc2VjdGlvbiAhPT0gX2NsaXBwaW5nLm51bUludGVyc2VjdGlvbiApICkge1xuXG5cdFx0XHRcdG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5uZWVkc1VwZGF0ZSApIHtcblxuXHRcdFx0aW5pdE1hdGVyaWFsKCBtYXRlcmlhbCwgZm9nLCBvYmplY3QgKTtcblx0XHRcdG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHR2YXIgcmVmcmVzaFByb2dyYW0gPSBmYWxzZTtcblx0XHR2YXIgcmVmcmVzaE1hdGVyaWFsID0gZmFsc2U7XG5cdFx0dmFyIHJlZnJlc2hMaWdodHMgPSBmYWxzZTtcblxuXHRcdHZhciBwcm9ncmFtID0gbWF0ZXJpYWxQcm9wZXJ0aWVzLnByb2dyYW0sXG5cdFx0XHRwX3VuaWZvcm1zID0gcHJvZ3JhbS5nZXRVbmlmb3JtcygpLFxuXHRcdFx0bV91bmlmb3JtcyA9IG1hdGVyaWFsUHJvcGVydGllcy5fX3dlYmdsU2hhZGVyLnVuaWZvcm1zO1xuXG5cdFx0aWYgKCBwcm9ncmFtLmlkICE9PSBfY3VycmVudFByb2dyYW0gKSB7XG5cblx0XHRcdF9nbC51c2VQcm9ncmFtKCBwcm9ncmFtLnByb2dyYW0gKTtcblx0XHRcdF9jdXJyZW50UHJvZ3JhbSA9IHByb2dyYW0uaWQ7XG5cblx0XHRcdHJlZnJlc2hQcm9ncmFtID0gdHJ1ZTtcblx0XHRcdHJlZnJlc2hNYXRlcmlhbCA9IHRydWU7XG5cdFx0XHRyZWZyZXNoTGlnaHRzID0gdHJ1ZTtcblxuXHRcdH1cblxuXHRcdGlmICggbWF0ZXJpYWwuaWQgIT09IF9jdXJyZW50TWF0ZXJpYWxJZCApIHtcblxuXHRcdFx0X2N1cnJlbnRNYXRlcmlhbElkID0gbWF0ZXJpYWwuaWQ7XG5cblx0XHRcdHJlZnJlc2hNYXRlcmlhbCA9IHRydWU7XG5cblx0XHR9XG5cblx0XHRpZiAoIHJlZnJlc2hQcm9ncmFtIHx8IGNhbWVyYSAhPT0gX2N1cnJlbnRDYW1lcmEgKSB7XG5cblx0XHRcdHBfdW5pZm9ybXMuc2V0VmFsdWUoIF9nbCwgJ3Byb2plY3Rpb25NYXRyaXgnLCBjYW1lcmEucHJvamVjdGlvbk1hdHJpeCApO1xuXG5cdFx0XHRpZiAoIGNhcGFiaWxpdGllcy5sb2dhcml0aG1pY0RlcHRoQnVmZmVyICkge1xuXG5cdFx0XHRcdHBfdW5pZm9ybXMuc2V0VmFsdWUoIF9nbCwgJ2xvZ0RlcHRoQnVmRkMnLFxuXHRcdFx0XHRcdDIuMCAvICggTWF0aC5sb2coIGNhbWVyYS5mYXIgKyAxLjAgKSAvIE1hdGguTE4yICkgKTtcblxuXHRcdFx0fVxuXG5cblx0XHRcdGlmICggY2FtZXJhICE9PSBfY3VycmVudENhbWVyYSApIHtcblxuXHRcdFx0XHRfY3VycmVudENhbWVyYSA9IGNhbWVyYTtcblxuXHRcdFx0XHQvLyBsaWdodGluZyB1bmlmb3JtcyBkZXBlbmQgb24gdGhlIGNhbWVyYSBzbyBlbmZvcmNlIGFuIHVwZGF0ZVxuXHRcdFx0XHQvLyBub3csIGluIGNhc2UgdGhpcyBtYXRlcmlhbCBzdXBwb3J0cyBsaWdodHMgLSBvciBsYXRlciwgd2hlblxuXHRcdFx0XHQvLyB0aGUgbmV4dCBtYXRlcmlhbCB0aGF0IGRvZXMgZ2V0cyBhY3RpdmF0ZWQ6XG5cblx0XHRcdFx0cmVmcmVzaE1hdGVyaWFsID0gdHJ1ZTtcdFx0Ly8gc2V0IHRvIHRydWUgb24gbWF0ZXJpYWwgY2hhbmdlXG5cdFx0XHRcdHJlZnJlc2hMaWdodHMgPSB0cnVlO1x0XHQvLyByZW1haW5zIHNldCB1bnRpbCB1cGRhdGUgZG9uZVxuXG5cdFx0XHR9XG5cblx0XHRcdC8vIGxvYWQgbWF0ZXJpYWwgc3BlY2lmaWMgdW5pZm9ybXNcblx0XHRcdC8vIChzaGFkZXIgbWF0ZXJpYWwgYWxzbyBnZXRzIHRoZW0gZm9yIHRoZSBzYWtlIG9mIGdlbmVyaWNpdHkpXG5cblx0XHRcdGlmICggbWF0ZXJpYWwuaXNTaGFkZXJNYXRlcmlhbCB8fFxuXHRcdFx0XHRtYXRlcmlhbC5pc01lc2hQaG9uZ01hdGVyaWFsIHx8XG5cdFx0XHRcdG1hdGVyaWFsLmlzTWVzaFN0YW5kYXJkTWF0ZXJpYWwgfHxcblx0XHRcdFx0bWF0ZXJpYWwuZW52TWFwICkge1xuXG5cdFx0XHRcdHZhciB1Q2FtUG9zID0gcF91bmlmb3Jtcy5tYXAuY2FtZXJhUG9zaXRpb247XG5cblx0XHRcdFx0aWYgKCB1Q2FtUG9zICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHR1Q2FtUG9zLnNldFZhbHVlKCBfZ2wsXG5cdFx0XHRcdFx0XHRfdmVjdG9yMy5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGNhbWVyYS5tYXRyaXhXb3JsZCApICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggbWF0ZXJpYWwuaXNNZXNoUGhvbmdNYXRlcmlhbCB8fFxuXHRcdFx0XHRtYXRlcmlhbC5pc01lc2hMYW1iZXJ0TWF0ZXJpYWwgfHxcblx0XHRcdFx0bWF0ZXJpYWwuaXNNZXNoQmFzaWNNYXRlcmlhbCB8fFxuXHRcdFx0XHRtYXRlcmlhbC5pc01lc2hTdGFuZGFyZE1hdGVyaWFsIHx8XG5cdFx0XHRcdG1hdGVyaWFsLmlzU2hhZGVyTWF0ZXJpYWwgfHxcblx0XHRcdFx0bWF0ZXJpYWwuc2tpbm5pbmcgKSB7XG5cblx0XHRcdFx0cF91bmlmb3Jtcy5zZXRWYWx1ZSggX2dsLCAndmlld01hdHJpeCcsIGNhbWVyYS5tYXRyaXhXb3JsZEludmVyc2UgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRwX3VuaWZvcm1zLnNldFZhbHVlKCBfZ2wsICd0b25lTWFwcGluZ0V4cG9zdXJlJywgX3RoaXMudG9uZU1hcHBpbmdFeHBvc3VyZSApO1xuXHRcdFx0cF91bmlmb3Jtcy5zZXRWYWx1ZSggX2dsLCAndG9uZU1hcHBpbmdXaGl0ZVBvaW50JywgX3RoaXMudG9uZU1hcHBpbmdXaGl0ZVBvaW50ICk7XG5cblx0XHR9XG5cblx0XHQvLyBza2lubmluZyB1bmlmb3JtcyBtdXN0IGJlIHNldCBldmVuIGlmIG1hdGVyaWFsIGRpZG4ndCBjaGFuZ2Vcblx0XHQvLyBhdXRvLXNldHRpbmcgb2YgdGV4dHVyZSB1bml0IGZvciBib25lIHRleHR1cmUgbXVzdCBnbyBiZWZvcmUgb3RoZXIgdGV4dHVyZXNcblx0XHQvLyBub3Qgc3VyZSB3aHksIGJ1dCBvdGhlcndpc2Ugd2VpcmQgdGhpbmdzIGhhcHBlblxuXG5cdFx0aWYgKCBtYXRlcmlhbC5za2lubmluZyApIHtcblxuXHRcdFx0cF91bmlmb3Jtcy5zZXRPcHRpb25hbCggX2dsLCBvYmplY3QsICdiaW5kTWF0cml4JyApO1xuXHRcdFx0cF91bmlmb3Jtcy5zZXRPcHRpb25hbCggX2dsLCBvYmplY3QsICdiaW5kTWF0cml4SW52ZXJzZScgKTtcblxuXHRcdFx0dmFyIHNrZWxldG9uID0gb2JqZWN0LnNrZWxldG9uO1xuXG5cdFx0XHRpZiAoIHNrZWxldG9uICkge1xuXG5cdFx0XHRcdHZhciBib25lcyA9IHNrZWxldG9uLmJvbmVzO1xuXG5cdFx0XHRcdGlmICggY2FwYWJpbGl0aWVzLmZsb2F0VmVydGV4VGV4dHVyZXMgKSB7XG5cblx0XHRcdFx0XHRpZiAoIHNrZWxldG9uLmJvbmVUZXh0dXJlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIGxheW91dCAoMSBtYXRyaXggPSA0IHBpeGVscylcblx0XHRcdFx0XHRcdC8vICAgICAgUkdCQSBSR0JBIFJHQkEgUkdCQSAoPT4gY29sdW1uMSwgY29sdW1uMiwgY29sdW1uMywgY29sdW1uNClcblx0XHRcdFx0XHRcdC8vICB3aXRoICA4eDggIHBpeGVsIHRleHR1cmUgbWF4ICAgMTYgYm9uZXMgKiA0IHBpeGVscyA9ICAoOCAqIDgpXG5cdFx0XHRcdFx0XHQvLyAgICAgICAxNngxNiBwaXhlbCB0ZXh0dXJlIG1heCAgIDY0IGJvbmVzICogNCBwaXhlbHMgPSAoMTYgKiAxNilcblx0XHRcdFx0XHRcdC8vICAgICAgIDMyeDMyIHBpeGVsIHRleHR1cmUgbWF4ICAyNTYgYm9uZXMgKiA0IHBpeGVscyA9ICgzMiAqIDMyKVxuXHRcdFx0XHRcdFx0Ly8gICAgICAgNjR4NjQgcGl4ZWwgdGV4dHVyZSBtYXggMTAyNCBib25lcyAqIDQgcGl4ZWxzID0gKDY0ICogNjQpXG5cblxuXHRcdFx0XHRcdFx0dmFyIHNpemUgPSBNYXRoLnNxcnQoIGJvbmVzLmxlbmd0aCAqIDQgKTsgLy8gNCBwaXhlbHMgbmVlZGVkIGZvciAxIG1hdHJpeFxuXHRcdFx0XHRcdFx0c2l6ZSA9IF9NYXRoLm5leHRQb3dlck9mVHdvKCBNYXRoLmNlaWwoIHNpemUgKSApO1xuXHRcdFx0XHRcdFx0c2l6ZSA9IE1hdGgubWF4KCBzaXplLCA0ICk7XG5cblx0XHRcdFx0XHRcdHZhciBib25lTWF0cmljZXMgPSBuZXcgRmxvYXQzMkFycmF5KCBzaXplICogc2l6ZSAqIDQgKTsgLy8gNCBmbG9hdHMgcGVyIFJHQkEgcGl4ZWxcblx0XHRcdFx0XHRcdGJvbmVNYXRyaWNlcy5zZXQoIHNrZWxldG9uLmJvbmVNYXRyaWNlcyApOyAvLyBjb3B5IGN1cnJlbnQgdmFsdWVzXG5cblx0XHRcdFx0XHRcdHZhciBib25lVGV4dHVyZSA9IG5ldyBEYXRhVGV4dHVyZSggYm9uZU1hdHJpY2VzLCBzaXplLCBzaXplLCBSR0JBRm9ybWF0LCBGbG9hdFR5cGUgKTtcblxuXHRcdFx0XHRcdFx0c2tlbGV0b24uYm9uZU1hdHJpY2VzID0gYm9uZU1hdHJpY2VzO1xuXHRcdFx0XHRcdFx0c2tlbGV0b24uYm9uZVRleHR1cmUgPSBib25lVGV4dHVyZTtcblx0XHRcdFx0XHRcdHNrZWxldG9uLmJvbmVUZXh0dXJlU2l6ZSA9IHNpemU7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwX3VuaWZvcm1zLnNldFZhbHVlKCBfZ2wsICdib25lVGV4dHVyZScsIHNrZWxldG9uLmJvbmVUZXh0dXJlICk7XG5cdFx0XHRcdFx0cF91bmlmb3Jtcy5zZXRWYWx1ZSggX2dsLCAnYm9uZVRleHR1cmVTaXplJywgc2tlbGV0b24uYm9uZVRleHR1cmVTaXplICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHBfdW5pZm9ybXMuc2V0T3B0aW9uYWwoIF9nbCwgc2tlbGV0b24sICdib25lTWF0cmljZXMnICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHJlZnJlc2hNYXRlcmlhbCApIHtcblxuXHRcdFx0aWYgKCBtYXRlcmlhbC5saWdodHMgKSB7XG5cblx0XHRcdFx0Ly8gdGhlIGN1cnJlbnQgbWF0ZXJpYWwgcmVxdWlyZXMgbGlnaHRpbmcgaW5mb1xuXG5cdFx0XHRcdC8vIG5vdGU6IGFsbCBsaWdodGluZyB1bmlmb3JtcyBhcmUgYWx3YXlzIHNldCBjb3JyZWN0bHlcblx0XHRcdFx0Ly8gdGhleSBzaW1wbHkgcmVmZXJlbmNlIHRoZSByZW5kZXJlcidzIHN0YXRlIGZvciB0aGVpclxuXHRcdFx0XHQvLyB2YWx1ZXNcblx0XHRcdFx0Ly9cblx0XHRcdFx0Ly8gdXNlIHRoZSBjdXJyZW50IG1hdGVyaWFsJ3MgLm5lZWRzVXBkYXRlIGZsYWdzIHRvIHNldFxuXHRcdFx0XHQvLyB0aGUgR0wgc3RhdGUgd2hlbiByZXF1aXJlZFxuXG5cdFx0XHRcdG1hcmtVbmlmb3Jtc0xpZ2h0c05lZWRzVXBkYXRlKCBtX3VuaWZvcm1zLCByZWZyZXNoTGlnaHRzICk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gcmVmcmVzaCB1bmlmb3JtcyBjb21tb24gdG8gc2V2ZXJhbCBtYXRlcmlhbHNcblxuXHRcdFx0aWYgKCBmb2cgJiYgbWF0ZXJpYWwuZm9nICkge1xuXG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc0ZvZyggbV91bmlmb3JtcywgZm9nICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBtYXRlcmlhbC5pc01lc2hCYXNpY01hdGVyaWFsIHx8XG5cdFx0XHRcdG1hdGVyaWFsLmlzTWVzaExhbWJlcnRNYXRlcmlhbCB8fFxuXHRcdFx0XHRtYXRlcmlhbC5pc01lc2hQaG9uZ01hdGVyaWFsIHx8XG5cdFx0XHRcdG1hdGVyaWFsLmlzTWVzaFN0YW5kYXJkTWF0ZXJpYWwgfHxcblx0XHRcdFx0bWF0ZXJpYWwuaXNNZXNoTm9ybWFsTWF0ZXJpYWwgfHxcblx0XHRcdFx0bWF0ZXJpYWwuaXNNZXNoRGVwdGhNYXRlcmlhbCApIHtcblxuXHRcdFx0XHRyZWZyZXNoVW5pZm9ybXNDb21tb24oIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gcmVmcmVzaCBzaW5nbGUgbWF0ZXJpYWwgc3BlY2lmaWMgdW5pZm9ybXNcblxuXHRcdFx0aWYgKCBtYXRlcmlhbC5pc0xpbmVCYXNpY01hdGVyaWFsICkge1xuXG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc0xpbmUoIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTGluZURhc2hlZE1hdGVyaWFsICkge1xuXG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc0xpbmUoIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc0Rhc2goIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzUG9pbnRzTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0cmVmcmVzaFVuaWZvcm1zUG9pbnRzKCBtX3VuaWZvcm1zLCBtYXRlcmlhbCApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC5pc01lc2hMYW1iZXJ0TWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0cmVmcmVzaFVuaWZvcm1zTGFtYmVydCggbV91bmlmb3JtcywgbWF0ZXJpYWwgKTtcblxuXHRcdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwuaXNNZXNoVG9vbk1hdGVyaWFsICkge1xuXG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc1Rvb24oIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTWVzaFBob25nTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0cmVmcmVzaFVuaWZvcm1zUGhvbmcoIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTWVzaFBoeXNpY2FsTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0cmVmcmVzaFVuaWZvcm1zUGh5c2ljYWwoIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTWVzaFN0YW5kYXJkTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0cmVmcmVzaFVuaWZvcm1zU3RhbmRhcmQoIG1fdW5pZm9ybXMsIG1hdGVyaWFsICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTWVzaERlcHRoTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0aWYgKCBtYXRlcmlhbC5kaXNwbGFjZW1lbnRNYXAgKSB7XG5cblx0XHRcdFx0XHRtX3VuaWZvcm1zLmRpc3BsYWNlbWVudE1hcC52YWx1ZSA9IG1hdGVyaWFsLmRpc3BsYWNlbWVudE1hcDtcblx0XHRcdFx0XHRtX3VuaWZvcm1zLmRpc3BsYWNlbWVudFNjYWxlLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50U2NhbGU7XG5cdFx0XHRcdFx0bV91bmlmb3Jtcy5kaXNwbGFjZW1lbnRCaWFzLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50QmlhcztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGVyaWFsLmlzTWVzaE5vcm1hbE1hdGVyaWFsICkge1xuXG5cdFx0XHRcdHJlZnJlc2hVbmlmb3Jtc05vcm1hbCggbV91bmlmb3JtcywgbWF0ZXJpYWwgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWN0QXJlYUxpZ2h0IFRleHR1cmVcblx0XHRcdC8vIFRPRE8gKG1yZG9vYik6IEZpbmQgYSBuaWNlciBpbXBsZW1lbnRhdGlvblxuXG5cdFx0XHRpZiAoIG1fdW5pZm9ybXMubHRjTWF0ICE9PSB1bmRlZmluZWQgKSBtX3VuaWZvcm1zLmx0Y01hdC52YWx1ZSA9IFVuaWZvcm1zTGliLkxUQ19NQVRfVEVYVFVSRTtcblx0XHRcdGlmICggbV91bmlmb3Jtcy5sdGNNYWcgIT09IHVuZGVmaW5lZCApIG1fdW5pZm9ybXMubHRjTWFnLnZhbHVlID0gVW5pZm9ybXNMaWIuTFRDX01BR19URVhUVVJFO1xuXG5cdFx0XHRXZWJHTFVuaWZvcm1zLnVwbG9hZChcblx0XHRcdFx0X2dsLCBtYXRlcmlhbFByb3BlcnRpZXMudW5pZm9ybXNMaXN0LCBtX3VuaWZvcm1zLCBfdGhpcyApO1xuXG5cdFx0fVxuXG5cblx0XHQvLyBjb21tb24gbWF0cmljZXNcblxuXHRcdHBfdW5pZm9ybXMuc2V0VmFsdWUoIF9nbCwgJ21vZGVsVmlld01hdHJpeCcsIG9iamVjdC5tb2RlbFZpZXdNYXRyaXggKTtcblx0XHRwX3VuaWZvcm1zLnNldFZhbHVlKCBfZ2wsICdub3JtYWxNYXRyaXgnLCBvYmplY3Qubm9ybWFsTWF0cml4ICk7XG5cdFx0cF91bmlmb3Jtcy5zZXRWYWx1ZSggX2dsLCAnbW9kZWxNYXRyaXgnLCBvYmplY3QubWF0cml4V29ybGQgKTtcblxuXHRcdHJldHVybiBwcm9ncmFtO1xuXG5cdH1cblxuXHQvLyBVbmlmb3JtcyAocmVmcmVzaCB1bmlmb3JtcyBvYmplY3RzKVxuXG5cdGZ1bmN0aW9uIHJlZnJlc2hVbmlmb3Jtc0NvbW1vbiggdW5pZm9ybXMsIG1hdGVyaWFsICkge1xuXG5cdFx0dW5pZm9ybXMub3BhY2l0eS52YWx1ZSA9IG1hdGVyaWFsLm9wYWNpdHk7XG5cblx0XHR1bmlmb3Jtcy5kaWZmdXNlLnZhbHVlID0gbWF0ZXJpYWwuY29sb3I7XG5cblx0XHRpZiAoIG1hdGVyaWFsLmVtaXNzaXZlICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5lbWlzc2l2ZS52YWx1ZS5jb3B5KCBtYXRlcmlhbC5lbWlzc2l2ZSApLm11bHRpcGx5U2NhbGFyKCBtYXRlcmlhbC5lbWlzc2l2ZUludGVuc2l0eSApO1xuXG5cdFx0fVxuXG5cdFx0dW5pZm9ybXMubWFwLnZhbHVlID0gbWF0ZXJpYWwubWFwO1xuXHRcdHVuaWZvcm1zLnNwZWN1bGFyTWFwLnZhbHVlID0gbWF0ZXJpYWwuc3BlY3VsYXJNYXA7XG5cdFx0dW5pZm9ybXMuYWxwaGFNYXAudmFsdWUgPSBtYXRlcmlhbC5hbHBoYU1hcDtcblxuXHRcdGlmICggbWF0ZXJpYWwubGlnaHRNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLmxpZ2h0TWFwLnZhbHVlID0gbWF0ZXJpYWwubGlnaHRNYXA7XG5cdFx0XHR1bmlmb3Jtcy5saWdodE1hcEludGVuc2l0eS52YWx1ZSA9IG1hdGVyaWFsLmxpZ2h0TWFwSW50ZW5zaXR5O1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5hb01hcCApIHtcblxuXHRcdFx0dW5pZm9ybXMuYW9NYXAudmFsdWUgPSBtYXRlcmlhbC5hb01hcDtcblx0XHRcdHVuaWZvcm1zLmFvTWFwSW50ZW5zaXR5LnZhbHVlID0gbWF0ZXJpYWwuYW9NYXBJbnRlbnNpdHk7XG5cblx0XHR9XG5cblx0XHQvLyB1diByZXBlYXQgYW5kIG9mZnNldCBzZXR0aW5nIHByaW9yaXRpZXNcblx0XHQvLyAxLiBjb2xvciBtYXBcblx0XHQvLyAyLiBzcGVjdWxhciBtYXBcblx0XHQvLyAzLiBub3JtYWwgbWFwXG5cdFx0Ly8gNC4gYnVtcCBtYXBcblx0XHQvLyA1LiBhbHBoYSBtYXBcblx0XHQvLyA2LiBlbWlzc2l2ZSBtYXBcblxuXHRcdHZhciB1dlNjYWxlTWFwO1xuXG5cdFx0aWYgKCBtYXRlcmlhbC5tYXAgKSB7XG5cblx0XHRcdHV2U2NhbGVNYXAgPSBtYXRlcmlhbC5tYXA7XG5cblx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC5zcGVjdWxhck1hcCApIHtcblxuXHRcdFx0dXZTY2FsZU1hcCA9IG1hdGVyaWFsLnNwZWN1bGFyTWFwO1xuXG5cdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwuZGlzcGxhY2VtZW50TWFwICkge1xuXG5cdFx0XHR1dlNjYWxlTWFwID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50TWFwO1xuXG5cdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwubm9ybWFsTWFwICkge1xuXG5cdFx0XHR1dlNjYWxlTWFwID0gbWF0ZXJpYWwubm9ybWFsTWFwO1xuXG5cdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwuYnVtcE1hcCApIHtcblxuXHRcdFx0dXZTY2FsZU1hcCA9IG1hdGVyaWFsLmJ1bXBNYXA7XG5cblx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC5yb3VnaG5lc3NNYXAgKSB7XG5cblx0XHRcdHV2U2NhbGVNYXAgPSBtYXRlcmlhbC5yb3VnaG5lc3NNYXA7XG5cblx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC5tZXRhbG5lc3NNYXAgKSB7XG5cblx0XHRcdHV2U2NhbGVNYXAgPSBtYXRlcmlhbC5tZXRhbG5lc3NNYXA7XG5cblx0XHR9IGVsc2UgaWYgKCBtYXRlcmlhbC5hbHBoYU1hcCApIHtcblxuXHRcdFx0dXZTY2FsZU1hcCA9IG1hdGVyaWFsLmFscGhhTWFwO1xuXG5cdFx0fSBlbHNlIGlmICggbWF0ZXJpYWwuZW1pc3NpdmVNYXAgKSB7XG5cblx0XHRcdHV2U2NhbGVNYXAgPSBtYXRlcmlhbC5lbWlzc2l2ZU1hcDtcblxuXHRcdH1cblxuXHRcdGlmICggdXZTY2FsZU1hcCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHQvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHRcdFx0aWYgKCB1dlNjYWxlTWFwLmlzV2ViR0xSZW5kZXJUYXJnZXQgKSB7XG5cblx0XHRcdFx0dXZTY2FsZU1hcCA9IHV2U2NhbGVNYXAudGV4dHVyZTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgb2Zmc2V0ID0gdXZTY2FsZU1hcC5vZmZzZXQ7XG5cdFx0XHR2YXIgcmVwZWF0ID0gdXZTY2FsZU1hcC5yZXBlYXQ7XG5cblx0XHRcdHVuaWZvcm1zLm9mZnNldFJlcGVhdC52YWx1ZS5zZXQoIG9mZnNldC54LCBvZmZzZXQueSwgcmVwZWF0LngsIHJlcGVhdC55ICk7XG5cblx0XHR9XG5cblx0XHR1bmlmb3Jtcy5lbnZNYXAudmFsdWUgPSBtYXRlcmlhbC5lbnZNYXA7XG5cblx0XHQvLyBkb24ndCBmbGlwIEN1YmVUZXh0dXJlIGVudk1hcHMsIGZsaXAgZXZlcnl0aGluZyBlbHNlOlxuXHRcdC8vICBXZWJHTFJlbmRlclRhcmdldEN1YmUgd2lsbCBiZSBmbGlwcGVkIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHRcdC8vICBXZWJHTFJlbmRlclRhcmdldEN1YmUudGV4dHVyZSB3aWxsIGJlIGZsaXBwZWQgYmVjYXVzZSBpdCdzIGEgVGV4dHVyZSBhbmQgTk9UIGEgQ3ViZVRleHR1cmVcblx0XHQvLyB0aGlzIGNoZWNrIG11c3QgYmUgaGFuZGxlZCBkaWZmZXJlbnRseSwgb3IgcmVtb3ZlZCBlbnRpcmVseSwgaWYgV2ViR0xSZW5kZXJUYXJnZXRDdWJlIHVzZXMgYSBDdWJlVGV4dHVyZSBpbiB0aGUgZnV0dXJlXG5cdFx0dW5pZm9ybXMuZmxpcEVudk1hcC52YWx1ZSA9ICggISAoIG1hdGVyaWFsLmVudk1hcCAmJiBtYXRlcmlhbC5lbnZNYXAuaXNDdWJlVGV4dHVyZSApICkgPyAxIDogLSAxO1xuXG5cdFx0dW5pZm9ybXMucmVmbGVjdGl2aXR5LnZhbHVlID0gbWF0ZXJpYWwucmVmbGVjdGl2aXR5O1xuXHRcdHVuaWZvcm1zLnJlZnJhY3Rpb25SYXRpby52YWx1ZSA9IG1hdGVyaWFsLnJlZnJhY3Rpb25SYXRpbztcblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVmcmVzaFVuaWZvcm1zTGluZSggdW5pZm9ybXMsIG1hdGVyaWFsICkge1xuXG5cdFx0dW5pZm9ybXMuZGlmZnVzZS52YWx1ZSA9IG1hdGVyaWFsLmNvbG9yO1xuXHRcdHVuaWZvcm1zLm9wYWNpdHkudmFsdWUgPSBtYXRlcmlhbC5vcGFjaXR5O1xuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNEYXNoKCB1bmlmb3JtcywgbWF0ZXJpYWwgKSB7XG5cblx0XHR1bmlmb3Jtcy5kYXNoU2l6ZS52YWx1ZSA9IG1hdGVyaWFsLmRhc2hTaXplO1xuXHRcdHVuaWZvcm1zLnRvdGFsU2l6ZS52YWx1ZSA9IG1hdGVyaWFsLmRhc2hTaXplICsgbWF0ZXJpYWwuZ2FwU2l6ZTtcblx0XHR1bmlmb3Jtcy5zY2FsZS52YWx1ZSA9IG1hdGVyaWFsLnNjYWxlO1xuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNQb2ludHMoIHVuaWZvcm1zLCBtYXRlcmlhbCApIHtcblxuXHRcdHVuaWZvcm1zLmRpZmZ1c2UudmFsdWUgPSBtYXRlcmlhbC5jb2xvcjtcblx0XHR1bmlmb3Jtcy5vcGFjaXR5LnZhbHVlID0gbWF0ZXJpYWwub3BhY2l0eTtcblx0XHR1bmlmb3Jtcy5zaXplLnZhbHVlID0gbWF0ZXJpYWwuc2l6ZSAqIF9waXhlbFJhdGlvO1xuXHRcdHVuaWZvcm1zLnNjYWxlLnZhbHVlID0gX2hlaWdodCAqIDAuNTtcblxuXHRcdHVuaWZvcm1zLm1hcC52YWx1ZSA9IG1hdGVyaWFsLm1hcDtcblxuXHRcdGlmICggbWF0ZXJpYWwubWFwICE9PSBudWxsICkge1xuXG5cdFx0XHR2YXIgb2Zmc2V0ID0gbWF0ZXJpYWwubWFwLm9mZnNldDtcblx0XHRcdHZhciByZXBlYXQgPSBtYXRlcmlhbC5tYXAucmVwZWF0O1xuXG5cdFx0XHR1bmlmb3Jtcy5vZmZzZXRSZXBlYXQudmFsdWUuc2V0KCBvZmZzZXQueCwgb2Zmc2V0LnksIHJlcGVhdC54LCByZXBlYXQueSApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNGb2coIHVuaWZvcm1zLCBmb2cgKSB7XG5cblx0XHR1bmlmb3Jtcy5mb2dDb2xvci52YWx1ZSA9IGZvZy5jb2xvcjtcblxuXHRcdGlmICggZm9nLmlzRm9nICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5mb2dOZWFyLnZhbHVlID0gZm9nLm5lYXI7XG5cdFx0XHR1bmlmb3Jtcy5mb2dGYXIudmFsdWUgPSBmb2cuZmFyO1xuXG5cdFx0fSBlbHNlIGlmICggZm9nLmlzRm9nRXhwMiApIHtcblxuXHRcdFx0dW5pZm9ybXMuZm9nRGVuc2l0eS52YWx1ZSA9IGZvZy5kZW5zaXR5O1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNMYW1iZXJ0KCB1bmlmb3JtcywgbWF0ZXJpYWwgKSB7XG5cblx0XHRpZiAoIG1hdGVyaWFsLmVtaXNzaXZlTWFwICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5lbWlzc2l2ZU1hcC52YWx1ZSA9IG1hdGVyaWFsLmVtaXNzaXZlTWFwO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNQaG9uZyggdW5pZm9ybXMsIG1hdGVyaWFsICkge1xuXG5cdFx0dW5pZm9ybXMuc3BlY3VsYXIudmFsdWUgPSBtYXRlcmlhbC5zcGVjdWxhcjtcblx0XHR1bmlmb3Jtcy5zaGluaW5lc3MudmFsdWUgPSBNYXRoLm1heCggbWF0ZXJpYWwuc2hpbmluZXNzLCAxZS00ICk7IC8vIHRvIHByZXZlbnQgcG93KCAwLjAsIDAuMCApXG5cblx0XHRpZiAoIG1hdGVyaWFsLmVtaXNzaXZlTWFwICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5lbWlzc2l2ZU1hcC52YWx1ZSA9IG1hdGVyaWFsLmVtaXNzaXZlTWFwO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5idW1wTWFwICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5idW1wTWFwLnZhbHVlID0gbWF0ZXJpYWwuYnVtcE1hcDtcblx0XHRcdHVuaWZvcm1zLmJ1bXBTY2FsZS52YWx1ZSA9IG1hdGVyaWFsLmJ1bXBTY2FsZTtcblxuXHRcdH1cblxuXHRcdGlmICggbWF0ZXJpYWwubm9ybWFsTWFwICkge1xuXG5cdFx0XHR1bmlmb3Jtcy5ub3JtYWxNYXAudmFsdWUgPSBtYXRlcmlhbC5ub3JtYWxNYXA7XG5cdFx0XHR1bmlmb3Jtcy5ub3JtYWxTY2FsZS52YWx1ZS5jb3B5KCBtYXRlcmlhbC5ub3JtYWxTY2FsZSApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5kaXNwbGFjZW1lbnRNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLmRpc3BsYWNlbWVudE1hcC52YWx1ZSA9IG1hdGVyaWFsLmRpc3BsYWNlbWVudE1hcDtcblx0XHRcdHVuaWZvcm1zLmRpc3BsYWNlbWVudFNjYWxlLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50U2NhbGU7XG5cdFx0XHR1bmlmb3Jtcy5kaXNwbGFjZW1lbnRCaWFzLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50QmlhcztcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVmcmVzaFVuaWZvcm1zVG9vbiggdW5pZm9ybXMsIG1hdGVyaWFsICkge1xuXG5cdFx0cmVmcmVzaFVuaWZvcm1zUGhvbmcoIHVuaWZvcm1zLCBtYXRlcmlhbCApO1xuXG5cdFx0aWYgKCBtYXRlcmlhbC5ncmFkaWVudE1hcCApIHtcblxuXHRcdFx0dW5pZm9ybXMuZ3JhZGllbnRNYXAudmFsdWUgPSBtYXRlcmlhbC5ncmFkaWVudE1hcDtcblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVmcmVzaFVuaWZvcm1zU3RhbmRhcmQoIHVuaWZvcm1zLCBtYXRlcmlhbCApIHtcblxuXHRcdHVuaWZvcm1zLnJvdWdobmVzcy52YWx1ZSA9IG1hdGVyaWFsLnJvdWdobmVzcztcblx0XHR1bmlmb3Jtcy5tZXRhbG5lc3MudmFsdWUgPSBtYXRlcmlhbC5tZXRhbG5lc3M7XG5cblx0XHRpZiAoIG1hdGVyaWFsLnJvdWdobmVzc01hcCApIHtcblxuXHRcdFx0dW5pZm9ybXMucm91Z2huZXNzTWFwLnZhbHVlID0gbWF0ZXJpYWwucm91Z2huZXNzTWFwO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5tZXRhbG5lc3NNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLm1ldGFsbmVzc01hcC52YWx1ZSA9IG1hdGVyaWFsLm1ldGFsbmVzc01hcDtcblxuXHRcdH1cblxuXHRcdGlmICggbWF0ZXJpYWwuZW1pc3NpdmVNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLmVtaXNzaXZlTWFwLnZhbHVlID0gbWF0ZXJpYWwuZW1pc3NpdmVNYXA7XG5cblx0XHR9XG5cblx0XHRpZiAoIG1hdGVyaWFsLmJ1bXBNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLmJ1bXBNYXAudmFsdWUgPSBtYXRlcmlhbC5idW1wTWFwO1xuXHRcdFx0dW5pZm9ybXMuYnVtcFNjYWxlLnZhbHVlID0gbWF0ZXJpYWwuYnVtcFNjYWxlO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5ub3JtYWxNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLm5vcm1hbE1hcC52YWx1ZSA9IG1hdGVyaWFsLm5vcm1hbE1hcDtcblx0XHRcdHVuaWZvcm1zLm5vcm1hbFNjYWxlLnZhbHVlLmNvcHkoIG1hdGVyaWFsLm5vcm1hbFNjYWxlICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIG1hdGVyaWFsLmRpc3BsYWNlbWVudE1hcCApIHtcblxuXHRcdFx0dW5pZm9ybXMuZGlzcGxhY2VtZW50TWFwLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50TWFwO1xuXHRcdFx0dW5pZm9ybXMuZGlzcGxhY2VtZW50U2NhbGUudmFsdWUgPSBtYXRlcmlhbC5kaXNwbGFjZW1lbnRTY2FsZTtcblx0XHRcdHVuaWZvcm1zLmRpc3BsYWNlbWVudEJpYXMudmFsdWUgPSBtYXRlcmlhbC5kaXNwbGFjZW1lbnRCaWFzO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5lbnZNYXAgKSB7XG5cblx0XHRcdC8vdW5pZm9ybXMuZW52TWFwLnZhbHVlID0gbWF0ZXJpYWwuZW52TWFwOyAvLyBwYXJ0IG9mIHVuaWZvcm1zIGNvbW1vblxuXHRcdFx0dW5pZm9ybXMuZW52TWFwSW50ZW5zaXR5LnZhbHVlID0gbWF0ZXJpYWwuZW52TWFwSW50ZW5zaXR5O1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXNQaHlzaWNhbCggdW5pZm9ybXMsIG1hdGVyaWFsICkge1xuXG5cdFx0dW5pZm9ybXMuY2xlYXJDb2F0LnZhbHVlID0gbWF0ZXJpYWwuY2xlYXJDb2F0O1xuXHRcdHVuaWZvcm1zLmNsZWFyQ29hdFJvdWdobmVzcy52YWx1ZSA9IG1hdGVyaWFsLmNsZWFyQ29hdFJvdWdobmVzcztcblxuXHRcdHJlZnJlc2hVbmlmb3Jtc1N0YW5kYXJkKCB1bmlmb3JtcywgbWF0ZXJpYWwgKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gcmVmcmVzaFVuaWZvcm1zTm9ybWFsKCB1bmlmb3JtcywgbWF0ZXJpYWwgKSB7XG5cblx0XHRpZiAoIG1hdGVyaWFsLmJ1bXBNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLmJ1bXBNYXAudmFsdWUgPSBtYXRlcmlhbC5idW1wTWFwO1xuXHRcdFx0dW5pZm9ybXMuYnVtcFNjYWxlLnZhbHVlID0gbWF0ZXJpYWwuYnVtcFNjYWxlO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBtYXRlcmlhbC5ub3JtYWxNYXAgKSB7XG5cblx0XHRcdHVuaWZvcm1zLm5vcm1hbE1hcC52YWx1ZSA9IG1hdGVyaWFsLm5vcm1hbE1hcDtcblx0XHRcdHVuaWZvcm1zLm5vcm1hbFNjYWxlLnZhbHVlLmNvcHkoIG1hdGVyaWFsLm5vcm1hbFNjYWxlICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIG1hdGVyaWFsLmRpc3BsYWNlbWVudE1hcCApIHtcblxuXHRcdFx0dW5pZm9ybXMuZGlzcGxhY2VtZW50TWFwLnZhbHVlID0gbWF0ZXJpYWwuZGlzcGxhY2VtZW50TWFwO1xuXHRcdFx0dW5pZm9ybXMuZGlzcGxhY2VtZW50U2NhbGUudmFsdWUgPSBtYXRlcmlhbC5kaXNwbGFjZW1lbnRTY2FsZTtcblx0XHRcdHVuaWZvcm1zLmRpc3BsYWNlbWVudEJpYXMudmFsdWUgPSBtYXRlcmlhbC5kaXNwbGFjZW1lbnRCaWFzO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBJZiB1bmlmb3JtcyBhcmUgbWFya2VkIGFzIGNsZWFuLCB0aGV5IGRvbid0IG5lZWQgdG8gYmUgbG9hZGVkIHRvIHRoZSBHUFUuXG5cblx0ZnVuY3Rpb24gbWFya1VuaWZvcm1zTGlnaHRzTmVlZHNVcGRhdGUoIHVuaWZvcm1zLCB2YWx1ZSApIHtcblxuXHRcdHVuaWZvcm1zLmFtYmllbnRMaWdodENvbG9yLm5lZWRzVXBkYXRlID0gdmFsdWU7XG5cblx0XHR1bmlmb3Jtcy5kaXJlY3Rpb25hbExpZ2h0cy5uZWVkc1VwZGF0ZSA9IHZhbHVlO1xuXHRcdHVuaWZvcm1zLnBvaW50TGlnaHRzLm5lZWRzVXBkYXRlID0gdmFsdWU7XG5cdFx0dW5pZm9ybXMuc3BvdExpZ2h0cy5uZWVkc1VwZGF0ZSA9IHZhbHVlO1xuXHRcdHVuaWZvcm1zLnJlY3RBcmVhTGlnaHRzLm5lZWRzVXBkYXRlID0gdmFsdWU7XG5cdFx0dW5pZm9ybXMuaGVtaXNwaGVyZUxpZ2h0cy5uZWVkc1VwZGF0ZSA9IHZhbHVlO1xuXG5cdH1cblxuXHQvLyBMaWdodGluZ1xuXG5cdGZ1bmN0aW9uIHNldHVwU2hhZG93cyggbGlnaHRzICkge1xuXG5cdFx0dmFyIGxpZ2h0U2hhZG93c0xlbmd0aCA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBsaWdodHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGxpZ2h0ID0gbGlnaHRzWyBpIF07XG5cblx0XHRcdGlmICggbGlnaHQuY2FzdFNoYWRvdyApIHtcblxuXHRcdFx0XHRfbGlnaHRzLnNoYWRvd3NbIGxpZ2h0U2hhZG93c0xlbmd0aCBdID0gbGlnaHQ7XG5cdFx0XHRcdGxpZ2h0U2hhZG93c0xlbmd0aCArKztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0X2xpZ2h0cy5zaGFkb3dzLmxlbmd0aCA9IGxpZ2h0U2hhZG93c0xlbmd0aDtcblxuXHR9XG5cblx0ZnVuY3Rpb24gc2V0dXBMaWdodHMoIGxpZ2h0cywgY2FtZXJhICkge1xuXG5cdFx0dmFyIGwsIGxsLCBsaWdodCwgc2hhZG93LFxuXHRcdFx0ciA9IDAsIGcgPSAwLCBiID0gMCxcblx0XHRcdGNvbG9yLFxuXHRcdFx0aW50ZW5zaXR5LFxuXHRcdFx0ZGlzdGFuY2UsXG5cdFx0XHRzaGFkb3dNYXAsXG5cblx0XHRcdHZpZXdNYXRyaXggPSBjYW1lcmEubWF0cml4V29ybGRJbnZlcnNlLFxuXG5cdFx0XHRkaXJlY3Rpb25hbExlbmd0aCA9IDAsXG5cdFx0XHRwb2ludExlbmd0aCA9IDAsXG5cdFx0XHRzcG90TGVuZ3RoID0gMCxcblx0XHRcdHJlY3RBcmVhTGVuZ3RoID0gMCxcblx0XHRcdGhlbWlMZW5ndGggPSAwO1xuXG5cdFx0Zm9yICggbCA9IDAsIGxsID0gbGlnaHRzLmxlbmd0aDsgbCA8IGxsOyBsICsrICkge1xuXG5cdFx0XHRsaWdodCA9IGxpZ2h0c1sgbCBdO1xuXG5cdFx0XHRjb2xvciA9IGxpZ2h0LmNvbG9yO1xuXHRcdFx0aW50ZW5zaXR5ID0gbGlnaHQuaW50ZW5zaXR5O1xuXHRcdFx0ZGlzdGFuY2UgPSBsaWdodC5kaXN0YW5jZTtcblxuXHRcdFx0c2hhZG93TWFwID0gKCBsaWdodC5zaGFkb3cgJiYgbGlnaHQuc2hhZG93Lm1hcCApID8gbGlnaHQuc2hhZG93Lm1hcC50ZXh0dXJlIDogbnVsbDtcblxuXHRcdFx0aWYgKCBsaWdodC5pc0FtYmllbnRMaWdodCApIHtcblxuXHRcdFx0XHRyICs9IGNvbG9yLnIgKiBpbnRlbnNpdHk7XG5cdFx0XHRcdGcgKz0gY29sb3IuZyAqIGludGVuc2l0eTtcblx0XHRcdFx0YiArPSBjb2xvci5iICogaW50ZW5zaXR5O1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBsaWdodC5pc0RpcmVjdGlvbmFsTGlnaHQgKSB7XG5cblx0XHRcdFx0dmFyIHVuaWZvcm1zID0gbGlnaHRDYWNoZS5nZXQoIGxpZ2h0ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMuY29sb3IuY29weSggbGlnaHQuY29sb3IgKS5tdWx0aXBseVNjYWxhciggbGlnaHQuaW50ZW5zaXR5ICk7XG5cdFx0XHRcdHVuaWZvcm1zLmRpcmVjdGlvbi5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGxpZ2h0Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdF92ZWN0b3IzLnNldEZyb21NYXRyaXhQb3NpdGlvbiggbGlnaHQudGFyZ2V0Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdHVuaWZvcm1zLmRpcmVjdGlvbi5zdWIoIF92ZWN0b3IzICk7XG5cdFx0XHRcdHVuaWZvcm1zLmRpcmVjdGlvbi50cmFuc2Zvcm1EaXJlY3Rpb24oIHZpZXdNYXRyaXggKTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3cgPSBsaWdodC5jYXN0U2hhZG93O1xuXG5cdFx0XHRcdGlmICggbGlnaHQuY2FzdFNoYWRvdyApIHtcblxuXHRcdFx0XHRcdHNoYWRvdyA9IGxpZ2h0LnNoYWRvdztcblxuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd0JpYXMgPSBzaGFkb3cuYmlhcztcblx0XHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3dSYWRpdXMgPSBzaGFkb3cucmFkaXVzO1xuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd01hcFNpemUgPSBzaGFkb3cubWFwU2l6ZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0X2xpZ2h0cy5kaXJlY3Rpb25hbFNoYWRvd01hcFsgZGlyZWN0aW9uYWxMZW5ndGggXSA9IHNoYWRvd01hcDtcblx0XHRcdFx0X2xpZ2h0cy5kaXJlY3Rpb25hbFNoYWRvd01hdHJpeFsgZGlyZWN0aW9uYWxMZW5ndGggXSA9IGxpZ2h0LnNoYWRvdy5tYXRyaXg7XG5cdFx0XHRcdF9saWdodHMuZGlyZWN0aW9uYWxbIGRpcmVjdGlvbmFsTGVuZ3RoIF0gPSB1bmlmb3JtcztcblxuXHRcdFx0XHRkaXJlY3Rpb25hbExlbmd0aCArKztcblxuXHRcdFx0fSBlbHNlIGlmICggbGlnaHQuaXNTcG90TGlnaHQgKSB7XG5cblx0XHRcdFx0dmFyIHVuaWZvcm1zID0gbGlnaHRDYWNoZS5nZXQoIGxpZ2h0ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBsaWdodC5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHR1bmlmb3Jtcy5wb3NpdGlvbi5hcHBseU1hdHJpeDQoIHZpZXdNYXRyaXggKTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5jb2xvci5jb3B5KCBjb2xvciApLm11bHRpcGx5U2NhbGFyKCBpbnRlbnNpdHkgKTtcblx0XHRcdFx0dW5pZm9ybXMuZGlzdGFuY2UgPSBkaXN0YW5jZTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5kaXJlY3Rpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBsaWdodC5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHRfdmVjdG9yMy5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGxpZ2h0LnRhcmdldC5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHR1bmlmb3Jtcy5kaXJlY3Rpb24uc3ViKCBfdmVjdG9yMyApO1xuXHRcdFx0XHR1bmlmb3Jtcy5kaXJlY3Rpb24udHJhbnNmb3JtRGlyZWN0aW9uKCB2aWV3TWF0cml4ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMuY29uZUNvcyA9IE1hdGguY29zKCBsaWdodC5hbmdsZSApO1xuXHRcdFx0XHR1bmlmb3Jtcy5wZW51bWJyYUNvcyA9IE1hdGguY29zKCBsaWdodC5hbmdsZSAqICggMSAtIGxpZ2h0LnBlbnVtYnJhICkgKTtcblx0XHRcdFx0dW5pZm9ybXMuZGVjYXkgPSAoIGxpZ2h0LmRpc3RhbmNlID09PSAwICkgPyAwLjAgOiBsaWdodC5kZWNheTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3cgPSBsaWdodC5jYXN0U2hhZG93O1xuXG5cdFx0XHRcdGlmICggbGlnaHQuY2FzdFNoYWRvdyApIHtcblxuXHRcdFx0XHRcdHNoYWRvdyA9IGxpZ2h0LnNoYWRvdztcblxuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd0JpYXMgPSBzaGFkb3cuYmlhcztcblx0XHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3dSYWRpdXMgPSBzaGFkb3cucmFkaXVzO1xuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd01hcFNpemUgPSBzaGFkb3cubWFwU2l6ZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0X2xpZ2h0cy5zcG90U2hhZG93TWFwWyBzcG90TGVuZ3RoIF0gPSBzaGFkb3dNYXA7XG5cdFx0XHRcdF9saWdodHMuc3BvdFNoYWRvd01hdHJpeFsgc3BvdExlbmd0aCBdID0gbGlnaHQuc2hhZG93Lm1hdHJpeDtcblx0XHRcdFx0X2xpZ2h0cy5zcG90WyBzcG90TGVuZ3RoIF0gPSB1bmlmb3JtcztcblxuXHRcdFx0XHRzcG90TGVuZ3RoICsrO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBsaWdodC5pc1JlY3RBcmVhTGlnaHQgKSB7XG5cblx0XHRcdFx0dmFyIHVuaWZvcm1zID0gbGlnaHRDYWNoZS5nZXQoIGxpZ2h0ICk7XG5cblx0XHRcdFx0Ly8gKGEpIGludGVuc2l0eSBjb250cm9scyBpcnJhZGlhbmNlIG9mIGVudGlyZSBsaWdodFxuXHRcdFx0XHR1bmlmb3Jtcy5jb2xvclxuXHRcdFx0XHRcdC5jb3B5KCBjb2xvciApXG5cdFx0XHRcdFx0Lm11bHRpcGx5U2NhbGFyKCBpbnRlbnNpdHkgLyAoIGxpZ2h0LndpZHRoICogbGlnaHQuaGVpZ2h0ICkgKTtcblxuXHRcdFx0XHQvLyAoYikgaW50ZW5zaXR5IGNvbnRyb2xzIHRoZSByYWRpYW5jZSBwZXIgbGlnaHQgYXJlYVxuXHRcdFx0XHQvLyB1bmlmb3Jtcy5jb2xvci5jb3B5KCBjb2xvciApLm11bHRpcGx5U2NhbGFyKCBpbnRlbnNpdHkgKTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5wb3NpdGlvbi5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGxpZ2h0Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdHVuaWZvcm1zLnBvc2l0aW9uLmFwcGx5TWF0cml4NCggdmlld01hdHJpeCApO1xuXG5cdFx0XHRcdC8vIGV4dHJhY3QgbG9jYWwgcm90YXRpb24gb2YgbGlnaHQgdG8gZGVyaXZlIHdpZHRoL2hlaWdodCBoYWxmIHZlY3RvcnNcblx0XHRcdFx0X21hdHJpeDQyLmlkZW50aXR5KCk7XG5cdFx0XHRcdF9tYXRyaXg0LmNvcHkoIGxpZ2h0Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdF9tYXRyaXg0LnByZW11bHRpcGx5KCB2aWV3TWF0cml4ICk7XG5cdFx0XHRcdF9tYXRyaXg0Mi5leHRyYWN0Um90YXRpb24oIF9tYXRyaXg0ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMuaGFsZldpZHRoLnNldCggbGlnaHQud2lkdGggKiAwLjUsICAgICAgICAgICAgICAgIDAuMCwgMC4wICk7XG5cdFx0XHRcdHVuaWZvcm1zLmhhbGZIZWlnaHQuc2V0KCAgICAgICAgICAgICAgMC4wLCBsaWdodC5oZWlnaHQgKiAwLjUsIDAuMCApO1xuXG5cdFx0XHRcdHVuaWZvcm1zLmhhbGZXaWR0aC5hcHBseU1hdHJpeDQoIF9tYXRyaXg0MiApO1xuXHRcdFx0XHR1bmlmb3Jtcy5oYWxmSGVpZ2h0LmFwcGx5TWF0cml4NCggX21hdHJpeDQyICk7XG5cblx0XHRcdFx0Ly8gVE9ETyAoYWJlbG5hdGlvbik6IFJlY3RBcmVhTGlnaHQgZGlzdGFuY2U/XG5cdFx0XHRcdC8vIHVuaWZvcm1zLmRpc3RhbmNlID0gZGlzdGFuY2U7XG5cblx0XHRcdFx0X2xpZ2h0cy5yZWN0QXJlYVsgcmVjdEFyZWFMZW5ndGggXSA9IHVuaWZvcm1zO1xuXG5cdFx0XHRcdHJlY3RBcmVhTGVuZ3RoICsrO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBsaWdodC5pc1BvaW50TGlnaHQgKSB7XG5cblx0XHRcdFx0dmFyIHVuaWZvcm1zID0gbGlnaHRDYWNoZS5nZXQoIGxpZ2h0ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBsaWdodC5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHR1bmlmb3Jtcy5wb3NpdGlvbi5hcHBseU1hdHJpeDQoIHZpZXdNYXRyaXggKTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5jb2xvci5jb3B5KCBsaWdodC5jb2xvciApLm11bHRpcGx5U2NhbGFyKCBsaWdodC5pbnRlbnNpdHkgKTtcblx0XHRcdFx0dW5pZm9ybXMuZGlzdGFuY2UgPSBsaWdodC5kaXN0YW5jZTtcblx0XHRcdFx0dW5pZm9ybXMuZGVjYXkgPSAoIGxpZ2h0LmRpc3RhbmNlID09PSAwICkgPyAwLjAgOiBsaWdodC5kZWNheTtcblxuXHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3cgPSBsaWdodC5jYXN0U2hhZG93O1xuXG5cdFx0XHRcdGlmICggbGlnaHQuY2FzdFNoYWRvdyApIHtcblxuXHRcdFx0XHRcdHNoYWRvdyA9IGxpZ2h0LnNoYWRvdztcblxuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd0JpYXMgPSBzaGFkb3cuYmlhcztcblx0XHRcdFx0XHR1bmlmb3Jtcy5zaGFkb3dSYWRpdXMgPSBzaGFkb3cucmFkaXVzO1xuXHRcdFx0XHRcdHVuaWZvcm1zLnNoYWRvd01hcFNpemUgPSBzaGFkb3cubWFwU2l6ZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0X2xpZ2h0cy5wb2ludFNoYWRvd01hcFsgcG9pbnRMZW5ndGggXSA9IHNoYWRvd01hcDtcblx0XHRcdFx0X2xpZ2h0cy5wb2ludFNoYWRvd01hdHJpeFsgcG9pbnRMZW5ndGggXSA9IGxpZ2h0LnNoYWRvdy5tYXRyaXg7XG5cdFx0XHRcdF9saWdodHMucG9pbnRbIHBvaW50TGVuZ3RoIF0gPSB1bmlmb3JtcztcblxuXHRcdFx0XHRwb2ludExlbmd0aCArKztcblxuXHRcdFx0fSBlbHNlIGlmICggbGlnaHQuaXNIZW1pc3BoZXJlTGlnaHQgKSB7XG5cblx0XHRcdFx0dmFyIHVuaWZvcm1zID0gbGlnaHRDYWNoZS5nZXQoIGxpZ2h0ICk7XG5cblx0XHRcdFx0dW5pZm9ybXMuZGlyZWN0aW9uLnNldEZyb21NYXRyaXhQb3NpdGlvbiggbGlnaHQubWF0cml4V29ybGQgKTtcblx0XHRcdFx0dW5pZm9ybXMuZGlyZWN0aW9uLnRyYW5zZm9ybURpcmVjdGlvbiggdmlld01hdHJpeCApO1xuXHRcdFx0XHR1bmlmb3Jtcy5kaXJlY3Rpb24ubm9ybWFsaXplKCk7XG5cblx0XHRcdFx0dW5pZm9ybXMuc2t5Q29sb3IuY29weSggbGlnaHQuY29sb3IgKS5tdWx0aXBseVNjYWxhciggaW50ZW5zaXR5ICk7XG5cdFx0XHRcdHVuaWZvcm1zLmdyb3VuZENvbG9yLmNvcHkoIGxpZ2h0Lmdyb3VuZENvbG9yICkubXVsdGlwbHlTY2FsYXIoIGludGVuc2l0eSApO1xuXG5cdFx0XHRcdF9saWdodHMuaGVtaVsgaGVtaUxlbmd0aCBdID0gdW5pZm9ybXM7XG5cblx0XHRcdFx0aGVtaUxlbmd0aCArKztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0X2xpZ2h0cy5hbWJpZW50WyAwIF0gPSByO1xuXHRcdF9saWdodHMuYW1iaWVudFsgMSBdID0gZztcblx0XHRfbGlnaHRzLmFtYmllbnRbIDIgXSA9IGI7XG5cblx0XHRfbGlnaHRzLmRpcmVjdGlvbmFsLmxlbmd0aCA9IGRpcmVjdGlvbmFsTGVuZ3RoO1xuXHRcdF9saWdodHMuc3BvdC5sZW5ndGggPSBzcG90TGVuZ3RoO1xuXHRcdF9saWdodHMucmVjdEFyZWEubGVuZ3RoID0gcmVjdEFyZWFMZW5ndGg7XG5cdFx0X2xpZ2h0cy5wb2ludC5sZW5ndGggPSBwb2ludExlbmd0aDtcblx0XHRfbGlnaHRzLmhlbWkubGVuZ3RoID0gaGVtaUxlbmd0aDtcblxuXHRcdC8vIFRPRE8gKHNhbS1nLXN0ZWVsKSB3aHkgYXJlbid0IHdlIHVzaW5nIGpvaW5cblx0XHRfbGlnaHRzLmhhc2ggPSBkaXJlY3Rpb25hbExlbmd0aCArICcsJyArIHBvaW50TGVuZ3RoICsgJywnICsgc3BvdExlbmd0aCArICcsJyArIHJlY3RBcmVhTGVuZ3RoICsgJywnICsgaGVtaUxlbmd0aCArICcsJyArIF9saWdodHMuc2hhZG93cy5sZW5ndGg7XG5cblx0fVxuXG5cdC8vIEdMIHN0YXRlIHNldHRpbmdcblxuXHR0aGlzLnNldEZhY2VDdWxsaW5nID0gZnVuY3Rpb24gKCBjdWxsRmFjZSwgZnJvbnRGYWNlRGlyZWN0aW9uICkge1xuXG5cdFx0c3RhdGUuc2V0Q3VsbEZhY2UoIGN1bGxGYWNlICk7XG5cdFx0c3RhdGUuc2V0RmxpcFNpZGVkKCBmcm9udEZhY2VEaXJlY3Rpb24gPT09IEZyb250RmFjZURpcmVjdGlvbkNXICk7XG5cblx0fTtcblxuXHQvLyBUZXh0dXJlc1xuXG5cdGZ1bmN0aW9uIGFsbG9jVGV4dHVyZVVuaXQoKSB7XG5cblx0XHR2YXIgdGV4dHVyZVVuaXQgPSBfdXNlZFRleHR1cmVVbml0cztcblxuXHRcdGlmICggdGV4dHVyZVVuaXQgPj0gY2FwYWJpbGl0aWVzLm1heFRleHR1cmVzICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdXZWJHTFJlbmRlcmVyOiB0cnlpbmcgdG8gdXNlICcgKyB0ZXh0dXJlVW5pdCArICcgdGV4dHVyZSB1bml0cyB3aGlsZSB0aGlzIEdQVSBzdXBwb3J0cyBvbmx5ICcgKyBjYXBhYmlsaXRpZXMubWF4VGV4dHVyZXMgKTtcblxuXHRcdH1cblxuXHRcdF91c2VkVGV4dHVyZVVuaXRzICs9IDE7XG5cblx0XHRyZXR1cm4gdGV4dHVyZVVuaXQ7XG5cblx0fVxuXG5cdHRoaXMuYWxsb2NUZXh0dXJlVW5pdCA9IGFsbG9jVGV4dHVyZVVuaXQ7XG5cblx0Ly8gdGhpcy5zZXRUZXh0dXJlMkQgPSBzZXRUZXh0dXJlMkQ7XG5cdHRoaXMuc2V0VGV4dHVyZTJEID0gKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgd2FybmVkID0gZmFsc2U7XG5cblx0XHQvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogcGVlbCB0ZXh0dXJlLnRleHR1cmVcblx0XHRyZXR1cm4gZnVuY3Rpb24gc2V0VGV4dHVyZTJEKCB0ZXh0dXJlLCBzbG90ICkge1xuXG5cdFx0XHRpZiAoIHRleHR1cmUgJiYgdGV4dHVyZS5pc1dlYkdMUmVuZGVyVGFyZ2V0ICkge1xuXG5cdFx0XHRcdGlmICggISB3YXJuZWQgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oIFwiVEhSRUUuV2ViR0xSZW5kZXJlci5zZXRUZXh0dXJlMkQ6IGRvbid0IHVzZSByZW5kZXIgdGFyZ2V0cyBhcyB0ZXh0dXJlcy4gVXNlIHRoZWlyIC50ZXh0dXJlIHByb3BlcnR5IGluc3RlYWQuXCIgKTtcblx0XHRcdFx0XHR3YXJuZWQgPSB0cnVlO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0ZXh0dXJlID0gdGV4dHVyZS50ZXh0dXJlO1xuXG5cdFx0XHR9XG5cblx0XHRcdHRleHR1cmVzLnNldFRleHR1cmUyRCggdGV4dHVyZSwgc2xvdCApO1xuXG5cdFx0fTtcblxuXHR9KCkgKTtcblxuXHR0aGlzLnNldFRleHR1cmUgPSAoIGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB3YXJuZWQgPSBmYWxzZTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiBzZXRUZXh0dXJlKCB0ZXh0dXJlLCBzbG90ICkge1xuXG5cdFx0XHRpZiAoICEgd2FybmVkICkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggXCJUSFJFRS5XZWJHTFJlbmRlcmVyOiAuc2V0VGV4dHVyZSBpcyBkZXByZWNhdGVkLCB1c2Ugc2V0VGV4dHVyZTJEIGluc3RlYWQuXCIgKTtcblx0XHRcdFx0d2FybmVkID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0ZXh0dXJlcy5zZXRUZXh0dXJlMkQoIHRleHR1cmUsIHNsb3QgKTtcblxuXHRcdH07XG5cblx0fSgpICk7XG5cblx0dGhpcy5zZXRUZXh0dXJlQ3ViZSA9ICggZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHdhcm5lZCA9IGZhbHNlO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHNldFRleHR1cmVDdWJlKCB0ZXh0dXJlLCBzbG90ICkge1xuXG5cdFx0XHQvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogcGVlbCB0ZXh0dXJlLnRleHR1cmVcblx0XHRcdGlmICggdGV4dHVyZSAmJiB0ZXh0dXJlLmlzV2ViR0xSZW5kZXJUYXJnZXRDdWJlICkge1xuXG5cdFx0XHRcdGlmICggISB3YXJuZWQgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oIFwiVEhSRUUuV2ViR0xSZW5kZXJlci5zZXRUZXh0dXJlQ3ViZTogZG9uJ3QgdXNlIGN1YmUgcmVuZGVyIHRhcmdldHMgYXMgdGV4dHVyZXMuIFVzZSB0aGVpciAudGV4dHVyZSBwcm9wZXJ0eSBpbnN0ZWFkLlwiICk7XG5cdFx0XHRcdFx0d2FybmVkID0gdHJ1ZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGV4dHVyZSA9IHRleHR1cmUudGV4dHVyZTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBjdXJyZW50bHkgcmVseWluZyBvbiB0aGUgZmFjdCB0aGF0IFdlYkdMUmVuZGVyVGFyZ2V0Q3ViZS50ZXh0dXJlIGlzIGEgVGV4dHVyZSBhbmQgTk9UIGEgQ3ViZVRleHR1cmVcblx0XHRcdC8vIFRPRE86IHVuaWZ5IHRoZXNlIGNvZGUgcGF0aHNcblx0XHRcdGlmICggKCB0ZXh0dXJlICYmIHRleHR1cmUuaXNDdWJlVGV4dHVyZSApIHx8XG5cdFx0XHRcdCggQXJyYXkuaXNBcnJheSggdGV4dHVyZS5pbWFnZSApICYmIHRleHR1cmUuaW1hZ2UubGVuZ3RoID09PSA2ICkgKSB7XG5cblx0XHRcdFx0Ly8gQ29tcHJlc3NlZFRleHR1cmUgY2FuIGhhdmUgQXJyYXkgaW4gaW1hZ2UgOi9cblxuXHRcdFx0XHQvLyB0aGlzIGZ1bmN0aW9uIGFsb25lIHNob3VsZCB0YWtlIGNhcmUgb2YgY3ViZSB0ZXh0dXJlc1xuXHRcdFx0XHR0ZXh0dXJlcy5zZXRUZXh0dXJlQ3ViZSggdGV4dHVyZSwgc2xvdCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIGFzc3VtZWQ6IHRleHR1cmUgcHJvcGVydHkgb2YgVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXRDdWJlXG5cblx0XHRcdFx0dGV4dHVyZXMuc2V0VGV4dHVyZUN1YmVEeW5hbWljKCB0ZXh0dXJlLCBzbG90ICk7XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fSgpICk7XG5cblx0dGhpcy5nZXRSZW5kZXJUYXJnZXQgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gX2N1cnJlbnRSZW5kZXJUYXJnZXQ7XG5cblx0fTtcblxuXHR0aGlzLnNldFJlbmRlclRhcmdldCA9IGZ1bmN0aW9uICggcmVuZGVyVGFyZ2V0ICkge1xuXG5cdFx0X2N1cnJlbnRSZW5kZXJUYXJnZXQgPSByZW5kZXJUYXJnZXQ7XG5cblx0XHRpZiAoIHJlbmRlclRhcmdldCAmJiBwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0ICkuX193ZWJnbEZyYW1lYnVmZmVyID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHRleHR1cmVzLnNldHVwUmVuZGVyVGFyZ2V0KCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdH1cblxuXHRcdHZhciBpc0N1YmUgPSAoIHJlbmRlclRhcmdldCAmJiByZW5kZXJUYXJnZXQuaXNXZWJHTFJlbmRlclRhcmdldEN1YmUgKTtcblx0XHR2YXIgZnJhbWVidWZmZXI7XG5cblx0XHRpZiAoIHJlbmRlclRhcmdldCApIHtcblxuXHRcdFx0dmFyIHJlbmRlclRhcmdldFByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0ICk7XG5cblx0XHRcdGlmICggaXNDdWJlICkge1xuXG5cdFx0XHRcdGZyYW1lYnVmZmVyID0gcmVuZGVyVGFyZ2V0UHJvcGVydGllcy5fX3dlYmdsRnJhbWVidWZmZXJbIHJlbmRlclRhcmdldC5hY3RpdmVDdWJlRmFjZSBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGZyYW1lYnVmZmVyID0gcmVuZGVyVGFyZ2V0UHJvcGVydGllcy5fX3dlYmdsRnJhbWVidWZmZXI7XG5cblx0XHRcdH1cblxuXHRcdFx0X2N1cnJlbnRTY2lzc29yLmNvcHkoIHJlbmRlclRhcmdldC5zY2lzc29yICk7XG5cdFx0XHRfY3VycmVudFNjaXNzb3JUZXN0ID0gcmVuZGVyVGFyZ2V0LnNjaXNzb3JUZXN0O1xuXG5cdFx0XHRfY3VycmVudFZpZXdwb3J0LmNvcHkoIHJlbmRlclRhcmdldC52aWV3cG9ydCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0ZnJhbWVidWZmZXIgPSBudWxsO1xuXG5cdFx0XHRfY3VycmVudFNjaXNzb3IuY29weSggX3NjaXNzb3IgKS5tdWx0aXBseVNjYWxhciggX3BpeGVsUmF0aW8gKTtcblx0XHRcdF9jdXJyZW50U2Npc3NvclRlc3QgPSBfc2Npc3NvclRlc3Q7XG5cblx0XHRcdF9jdXJyZW50Vmlld3BvcnQuY29weSggX3ZpZXdwb3J0ICkubXVsdGlwbHlTY2FsYXIoIF9waXhlbFJhdGlvICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIF9jdXJyZW50RnJhbWVidWZmZXIgIT09IGZyYW1lYnVmZmVyICkge1xuXG5cdFx0XHRfZ2wuYmluZEZyYW1lYnVmZmVyKCBfZ2wuRlJBTUVCVUZGRVIsIGZyYW1lYnVmZmVyICk7XG5cdFx0XHRfY3VycmVudEZyYW1lYnVmZmVyID0gZnJhbWVidWZmZXI7XG5cblx0XHR9XG5cblx0XHRzdGF0ZS5zY2lzc29yKCBfY3VycmVudFNjaXNzb3IgKTtcblx0XHRzdGF0ZS5zZXRTY2lzc29yVGVzdCggX2N1cnJlbnRTY2lzc29yVGVzdCApO1xuXG5cdFx0c3RhdGUudmlld3BvcnQoIF9jdXJyZW50Vmlld3BvcnQgKTtcblxuXHRcdGlmICggaXNDdWJlICkge1xuXG5cdFx0XHR2YXIgdGV4dHVyZVByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzLmdldCggcmVuZGVyVGFyZ2V0LnRleHR1cmUgKTtcblx0XHRcdF9nbC5mcmFtZWJ1ZmZlclRleHR1cmUyRCggX2dsLkZSQU1FQlVGRkVSLCBfZ2wuQ09MT1JfQVRUQUNITUVOVDAsIF9nbC5URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1ggKyByZW5kZXJUYXJnZXQuYWN0aXZlQ3ViZUZhY2UsIHRleHR1cmVQcm9wZXJ0aWVzLl9fd2ViZ2xUZXh0dXJlLCByZW5kZXJUYXJnZXQuYWN0aXZlTWlwTWFwTGV2ZWwgKTtcblxuXHRcdH1cblxuXHR9O1xuXG5cdHRoaXMucmVhZFJlbmRlclRhcmdldFBpeGVscyA9IGZ1bmN0aW9uICggcmVuZGVyVGFyZ2V0LCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCBidWZmZXIgKSB7XG5cblx0XHRpZiAoICggcmVuZGVyVGFyZ2V0ICYmIHJlbmRlclRhcmdldC5pc1dlYkdMUmVuZGVyVGFyZ2V0ICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xSZW5kZXJlci5yZWFkUmVuZGVyVGFyZ2V0UGl4ZWxzOiByZW5kZXJUYXJnZXQgaXMgbm90IFRIUkVFLldlYkdMUmVuZGVyVGFyZ2V0LicgKTtcblx0XHRcdHJldHVybjtcblxuXHRcdH1cblxuXHRcdHZhciBmcmFtZWJ1ZmZlciA9IHByb3BlcnRpZXMuZ2V0KCByZW5kZXJUYXJnZXQgKS5fX3dlYmdsRnJhbWVidWZmZXI7XG5cblx0XHRpZiAoIGZyYW1lYnVmZmVyICkge1xuXG5cdFx0XHR2YXIgcmVzdG9yZSA9IGZhbHNlO1xuXG5cdFx0XHRpZiAoIGZyYW1lYnVmZmVyICE9PSBfY3VycmVudEZyYW1lYnVmZmVyICkge1xuXG5cdFx0XHRcdF9nbC5iaW5kRnJhbWVidWZmZXIoIF9nbC5GUkFNRUJVRkZFUiwgZnJhbWVidWZmZXIgKTtcblxuXHRcdFx0XHRyZXN0b3JlID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXG5cdFx0XHRcdHZhciB0ZXh0dXJlID0gcmVuZGVyVGFyZ2V0LnRleHR1cmU7XG5cdFx0XHRcdHZhciB0ZXh0dXJlRm9ybWF0ID0gdGV4dHVyZS5mb3JtYXQ7XG5cdFx0XHRcdHZhciB0ZXh0dXJlVHlwZSA9IHRleHR1cmUudHlwZTtcblxuXHRcdFx0XHRpZiAoIHRleHR1cmVGb3JtYXQgIT09IFJHQkFGb3JtYXQgJiYgcGFyYW1UaHJlZVRvR0woIHRleHR1cmVGb3JtYXQgKSAhPT0gX2dsLmdldFBhcmFtZXRlciggX2dsLklNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfRk9STUFUICkgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xSZW5kZXJlci5yZWFkUmVuZGVyVGFyZ2V0UGl4ZWxzOiByZW5kZXJUYXJnZXQgaXMgbm90IGluIFJHQkEgb3IgaW1wbGVtZW50YXRpb24gZGVmaW5lZCBmb3JtYXQuJyApO1xuXHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCB0ZXh0dXJlVHlwZSAhPT0gVW5zaWduZWRCeXRlVHlwZSAmJiBwYXJhbVRocmVlVG9HTCggdGV4dHVyZVR5cGUgKSAhPT0gX2dsLmdldFBhcmFtZXRlciggX2dsLklNUExFTUVOVEFUSU9OX0NPTE9SX1JFQURfVFlQRSApICYmIC8vIElFMTEsIEVkZ2UgYW5kIENocm9tZSBNYWMgPCA1MiAoIzk1MTMpXG5cdFx0XHRcdFx0ISAoIHRleHR1cmVUeXBlID09PSBGbG9hdFR5cGUgJiYgKCBleHRlbnNpb25zLmdldCggJ09FU190ZXh0dXJlX2Zsb2F0JyApIHx8IGV4dGVuc2lvbnMuZ2V0KCAnV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0JyApICkgKSAmJiAvLyBDaHJvbWUgTWFjID49IDUyIGFuZCBGaXJlZm94XG5cdFx0XHRcdFx0ISAoIHRleHR1cmVUeXBlID09PSBIYWxmRmxvYXRUeXBlICYmIGV4dGVuc2lvbnMuZ2V0KCAnRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0JyApICkgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xSZW5kZXJlci5yZWFkUmVuZGVyVGFyZ2V0UGl4ZWxzOiByZW5kZXJUYXJnZXQgaXMgbm90IGluIFVuc2lnbmVkQnl0ZVR5cGUgb3IgaW1wbGVtZW50YXRpb24gZGVmaW5lZCB0eXBlLicgKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggX2dsLmNoZWNrRnJhbWVidWZmZXJTdGF0dXMoIF9nbC5GUkFNRUJVRkZFUiApID09PSBfZ2wuRlJBTUVCVUZGRVJfQ09NUExFVEUgKSB7XG5cblx0XHRcdFx0XHQvLyB0aGUgZm9sbG93aW5nIGlmIHN0YXRlbWVudCBlbnN1cmVzIHZhbGlkIHJlYWQgcmVxdWVzdHMgKG5vIG91dC1vZi1ib3VuZHMgcGl4ZWxzLCBzZWUgIzg2MDQpXG5cblx0XHRcdFx0XHRpZiAoICggeCA+PSAwICYmIHggPD0gKCByZW5kZXJUYXJnZXQud2lkdGggLSB3aWR0aCApICkgJiYgKCB5ID49IDAgJiYgeSA8PSAoIHJlbmRlclRhcmdldC5oZWlnaHQgLSBoZWlnaHQgKSApICkge1xuXG5cdFx0XHRcdFx0XHRfZ2wucmVhZFBpeGVscyggeCwgeSwgd2lkdGgsIGhlaWdodCwgcGFyYW1UaHJlZVRvR0woIHRleHR1cmVGb3JtYXQgKSwgcGFyYW1UaHJlZVRvR0woIHRleHR1cmVUeXBlICksIGJ1ZmZlciApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuV2ViR0xSZW5kZXJlci5yZWFkUmVuZGVyVGFyZ2V0UGl4ZWxzOiByZWFkUGl4ZWxzIGZyb20gcmVuZGVyVGFyZ2V0IGZhaWxlZC4gRnJhbWVidWZmZXIgbm90IGNvbXBsZXRlLicgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZmluYWxseSB7XG5cblx0XHRcdFx0aWYgKCByZXN0b3JlICkge1xuXG5cdFx0XHRcdFx0X2dsLmJpbmRGcmFtZWJ1ZmZlciggX2dsLkZSQU1FQlVGRkVSLCBfY3VycmVudEZyYW1lYnVmZmVyICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fTtcblxuXHQvLyBNYXAgdGhyZWUuanMgY29uc3RhbnRzIHRvIFdlYkdMIGNvbnN0YW50c1xuXG5cdGZ1bmN0aW9uIHBhcmFtVGhyZWVUb0dMKCBwICkge1xuXG5cdFx0dmFyIGV4dGVuc2lvbjtcblxuXHRcdGlmICggcCA9PT0gUmVwZWF0V3JhcHBpbmcgKSByZXR1cm4gX2dsLlJFUEVBVDtcblx0XHRpZiAoIHAgPT09IENsYW1wVG9FZGdlV3JhcHBpbmcgKSByZXR1cm4gX2dsLkNMQU1QX1RPX0VER0U7XG5cdFx0aWYgKCBwID09PSBNaXJyb3JlZFJlcGVhdFdyYXBwaW5nICkgcmV0dXJuIF9nbC5NSVJST1JFRF9SRVBFQVQ7XG5cblx0XHRpZiAoIHAgPT09IE5lYXJlc3RGaWx0ZXIgKSByZXR1cm4gX2dsLk5FQVJFU1Q7XG5cdFx0aWYgKCBwID09PSBOZWFyZXN0TWlwTWFwTmVhcmVzdEZpbHRlciApIHJldHVybiBfZ2wuTkVBUkVTVF9NSVBNQVBfTkVBUkVTVDtcblx0XHRpZiAoIHAgPT09IE5lYXJlc3RNaXBNYXBMaW5lYXJGaWx0ZXIgKSByZXR1cm4gX2dsLk5FQVJFU1RfTUlQTUFQX0xJTkVBUjtcblxuXHRcdGlmICggcCA9PT0gTGluZWFyRmlsdGVyICkgcmV0dXJuIF9nbC5MSU5FQVI7XG5cdFx0aWYgKCBwID09PSBMaW5lYXJNaXBNYXBOZWFyZXN0RmlsdGVyICkgcmV0dXJuIF9nbC5MSU5FQVJfTUlQTUFQX05FQVJFU1Q7XG5cdFx0aWYgKCBwID09PSBMaW5lYXJNaXBNYXBMaW5lYXJGaWx0ZXIgKSByZXR1cm4gX2dsLkxJTkVBUl9NSVBNQVBfTElORUFSO1xuXG5cdFx0aWYgKCBwID09PSBVbnNpZ25lZEJ5dGVUeXBlICkgcmV0dXJuIF9nbC5VTlNJR05FRF9CWVRFO1xuXHRcdGlmICggcCA9PT0gVW5zaWduZWRTaG9ydDQ0NDRUeXBlICkgcmV0dXJuIF9nbC5VTlNJR05FRF9TSE9SVF80XzRfNF80O1xuXHRcdGlmICggcCA9PT0gVW5zaWduZWRTaG9ydDU1NTFUeXBlICkgcmV0dXJuIF9nbC5VTlNJR05FRF9TSE9SVF81XzVfNV8xO1xuXHRcdGlmICggcCA9PT0gVW5zaWduZWRTaG9ydDU2NVR5cGUgKSByZXR1cm4gX2dsLlVOU0lHTkVEX1NIT1JUXzVfNl81O1xuXG5cdFx0aWYgKCBwID09PSBCeXRlVHlwZSApIHJldHVybiBfZ2wuQllURTtcblx0XHRpZiAoIHAgPT09IFNob3J0VHlwZSApIHJldHVybiBfZ2wuU0hPUlQ7XG5cdFx0aWYgKCBwID09PSBVbnNpZ25lZFNob3J0VHlwZSApIHJldHVybiBfZ2wuVU5TSUdORURfU0hPUlQ7XG5cdFx0aWYgKCBwID09PSBJbnRUeXBlICkgcmV0dXJuIF9nbC5JTlQ7XG5cdFx0aWYgKCBwID09PSBVbnNpZ25lZEludFR5cGUgKSByZXR1cm4gX2dsLlVOU0lHTkVEX0lOVDtcblx0XHRpZiAoIHAgPT09IEZsb2F0VHlwZSApIHJldHVybiBfZ2wuRkxPQVQ7XG5cblx0XHRpZiAoIHAgPT09IEhhbGZGbG9hdFR5cGUgKSB7XG5cblx0XHRcdGV4dGVuc2lvbiA9IGV4dGVuc2lvbnMuZ2V0KCAnT0VTX3RleHR1cmVfaGFsZl9mbG9hdCcgKTtcblxuXHRcdFx0aWYgKCBleHRlbnNpb24gIT09IG51bGwgKSByZXR1cm4gZXh0ZW5zaW9uLkhBTEZfRkxPQVRfT0VTO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBwID09PSBBbHBoYUZvcm1hdCApIHJldHVybiBfZ2wuQUxQSEE7XG5cdFx0aWYgKCBwID09PSBSR0JGb3JtYXQgKSByZXR1cm4gX2dsLlJHQjtcblx0XHRpZiAoIHAgPT09IFJHQkFGb3JtYXQgKSByZXR1cm4gX2dsLlJHQkE7XG5cdFx0aWYgKCBwID09PSBMdW1pbmFuY2VGb3JtYXQgKSByZXR1cm4gX2dsLkxVTUlOQU5DRTtcblx0XHRpZiAoIHAgPT09IEx1bWluYW5jZUFscGhhRm9ybWF0ICkgcmV0dXJuIF9nbC5MVU1JTkFOQ0VfQUxQSEE7XG5cdFx0aWYgKCBwID09PSBEZXB0aEZvcm1hdCApIHJldHVybiBfZ2wuREVQVEhfQ09NUE9ORU5UO1xuXHRcdGlmICggcCA9PT0gRGVwdGhTdGVuY2lsRm9ybWF0ICkgcmV0dXJuIF9nbC5ERVBUSF9TVEVOQ0lMO1xuXG5cdFx0aWYgKCBwID09PSBBZGRFcXVhdGlvbiApIHJldHVybiBfZ2wuRlVOQ19BREQ7XG5cdFx0aWYgKCBwID09PSBTdWJ0cmFjdEVxdWF0aW9uICkgcmV0dXJuIF9nbC5GVU5DX1NVQlRSQUNUO1xuXHRcdGlmICggcCA9PT0gUmV2ZXJzZVN1YnRyYWN0RXF1YXRpb24gKSByZXR1cm4gX2dsLkZVTkNfUkVWRVJTRV9TVUJUUkFDVDtcblxuXHRcdGlmICggcCA9PT0gWmVyb0ZhY3RvciApIHJldHVybiBfZ2wuWkVSTztcblx0XHRpZiAoIHAgPT09IE9uZUZhY3RvciApIHJldHVybiBfZ2wuT05FO1xuXHRcdGlmICggcCA9PT0gU3JjQ29sb3JGYWN0b3IgKSByZXR1cm4gX2dsLlNSQ19DT0xPUjtcblx0XHRpZiAoIHAgPT09IE9uZU1pbnVzU3JjQ29sb3JGYWN0b3IgKSByZXR1cm4gX2dsLk9ORV9NSU5VU19TUkNfQ09MT1I7XG5cdFx0aWYgKCBwID09PSBTcmNBbHBoYUZhY3RvciApIHJldHVybiBfZ2wuU1JDX0FMUEhBO1xuXHRcdGlmICggcCA9PT0gT25lTWludXNTcmNBbHBoYUZhY3RvciApIHJldHVybiBfZ2wuT05FX01JTlVTX1NSQ19BTFBIQTtcblx0XHRpZiAoIHAgPT09IERzdEFscGhhRmFjdG9yICkgcmV0dXJuIF9nbC5EU1RfQUxQSEE7XG5cdFx0aWYgKCBwID09PSBPbmVNaW51c0RzdEFscGhhRmFjdG9yICkgcmV0dXJuIF9nbC5PTkVfTUlOVVNfRFNUX0FMUEhBO1xuXG5cdFx0aWYgKCBwID09PSBEc3RDb2xvckZhY3RvciApIHJldHVybiBfZ2wuRFNUX0NPTE9SO1xuXHRcdGlmICggcCA9PT0gT25lTWludXNEc3RDb2xvckZhY3RvciApIHJldHVybiBfZ2wuT05FX01JTlVTX0RTVF9DT0xPUjtcblx0XHRpZiAoIHAgPT09IFNyY0FscGhhU2F0dXJhdGVGYWN0b3IgKSByZXR1cm4gX2dsLlNSQ19BTFBIQV9TQVRVUkFURTtcblxuXHRcdGlmICggcCA9PT0gUkdCX1MzVENfRFhUMV9Gb3JtYXQgfHwgcCA9PT0gUkdCQV9TM1RDX0RYVDFfRm9ybWF0IHx8XG5cdFx0XHRwID09PSBSR0JBX1MzVENfRFhUM19Gb3JtYXQgfHwgcCA9PT0gUkdCQV9TM1RDX0RYVDVfRm9ybWF0ICkge1xuXG5cdFx0XHRleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9zM3RjJyApO1xuXG5cdFx0XHRpZiAoIGV4dGVuc2lvbiAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHRpZiAoIHAgPT09IFJHQl9TM1RDX0RYVDFfRm9ybWF0ICkgcmV0dXJuIGV4dGVuc2lvbi5DT01QUkVTU0VEX1JHQl9TM1RDX0RYVDFfRVhUO1xuXHRcdFx0XHRpZiAoIHAgPT09IFJHQkFfUzNUQ19EWFQxX0Zvcm1hdCApIHJldHVybiBleHRlbnNpb24uQ09NUFJFU1NFRF9SR0JBX1MzVENfRFhUMV9FWFQ7XG5cdFx0XHRcdGlmICggcCA9PT0gUkdCQV9TM1RDX0RYVDNfRm9ybWF0ICkgcmV0dXJuIGV4dGVuc2lvbi5DT01QUkVTU0VEX1JHQkFfUzNUQ19EWFQzX0VYVDtcblx0XHRcdFx0aWYgKCBwID09PSBSR0JBX1MzVENfRFhUNV9Gb3JtYXQgKSByZXR1cm4gZXh0ZW5zaW9uLkNPTVBSRVNTRURfUkdCQV9TM1RDX0RYVDVfRVhUO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHAgPT09IFJHQl9QVlJUQ180QlBQVjFfRm9ybWF0IHx8IHAgPT09IFJHQl9QVlJUQ18yQlBQVjFfRm9ybWF0IHx8XG5cdFx0XHRwID09PSBSR0JBX1BWUlRDXzRCUFBWMV9Gb3JtYXQgfHwgcCA9PT0gUkdCQV9QVlJUQ18yQlBQVjFfRm9ybWF0ICkge1xuXG5cdFx0XHRleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9wdnJ0YycgKTtcblxuXHRcdFx0aWYgKCBleHRlbnNpb24gIT09IG51bGwgKSB7XG5cblx0XHRcdFx0aWYgKCBwID09PSBSR0JfUFZSVENfNEJQUFYxX0Zvcm1hdCApIHJldHVybiBleHRlbnNpb24uQ09NUFJFU1NFRF9SR0JfUFZSVENfNEJQUFYxX0lNRztcblx0XHRcdFx0aWYgKCBwID09PSBSR0JfUFZSVENfMkJQUFYxX0Zvcm1hdCApIHJldHVybiBleHRlbnNpb24uQ09NUFJFU1NFRF9SR0JfUFZSVENfMkJQUFYxX0lNRztcblx0XHRcdFx0aWYgKCBwID09PSBSR0JBX1BWUlRDXzRCUFBWMV9Gb3JtYXQgKSByZXR1cm4gZXh0ZW5zaW9uLkNPTVBSRVNTRURfUkdCQV9QVlJUQ180QlBQVjFfSU1HO1xuXHRcdFx0XHRpZiAoIHAgPT09IFJHQkFfUFZSVENfMkJQUFYxX0Zvcm1hdCApIHJldHVybiBleHRlbnNpb24uQ09NUFJFU1NFRF9SR0JBX1BWUlRDXzJCUFBWMV9JTUc7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggcCA9PT0gUkdCX0VUQzFfRm9ybWF0ICkge1xuXG5cdFx0XHRleHRlbnNpb24gPSBleHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9ldGMxJyApO1xuXG5cdFx0XHRpZiAoIGV4dGVuc2lvbiAhPT0gbnVsbCApIHJldHVybiBleHRlbnNpb24uQ09NUFJFU1NFRF9SR0JfRVRDMV9XRUJHTDtcblxuXHRcdH1cblxuXHRcdGlmICggcCA9PT0gTWluRXF1YXRpb24gfHwgcCA9PT0gTWF4RXF1YXRpb24gKSB7XG5cblx0XHRcdGV4dGVuc2lvbiA9IGV4dGVuc2lvbnMuZ2V0KCAnRVhUX2JsZW5kX21pbm1heCcgKTtcblxuXHRcdFx0aWYgKCBleHRlbnNpb24gIT09IG51bGwgKSB7XG5cblx0XHRcdFx0aWYgKCBwID09PSBNaW5FcXVhdGlvbiApIHJldHVybiBleHRlbnNpb24uTUlOX0VYVDtcblx0XHRcdFx0aWYgKCBwID09PSBNYXhFcXVhdGlvbiApIHJldHVybiBleHRlbnNpb24uTUFYX0VYVDtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aWYgKCBwID09PSBVbnNpZ25lZEludDI0OFR5cGUgKSB7XG5cblx0XHRcdGV4dGVuc2lvbiA9IGV4dGVuc2lvbnMuZ2V0KCAnV0VCR0xfZGVwdGhfdGV4dHVyZScgKTtcblxuXHRcdFx0aWYgKCBleHRlbnNpb24gIT09IG51bGwgKSByZXR1cm4gZXh0ZW5zaW9uLlVOU0lHTkVEX0lOVF8yNF84X1dFQkdMO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIDA7XG5cblx0fVxuXG59XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gRm9nRXhwMiAoIGNvbG9yLCBkZW5zaXR5ICkge1xuXG5cdHRoaXMubmFtZSA9ICcnO1xuXG5cdHRoaXMuY29sb3IgPSBuZXcgQ29sb3IoIGNvbG9yICk7XG5cdHRoaXMuZGVuc2l0eSA9ICggZGVuc2l0eSAhPT0gdW5kZWZpbmVkICkgPyBkZW5zaXR5IDogMC4wMDAyNTtcblxufVxuXG5Gb2dFeHAyLnByb3RvdHlwZS5pc0ZvZ0V4cDIgPSB0cnVlO1xuXG5Gb2dFeHAyLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcblxuXHRyZXR1cm4gbmV3IEZvZ0V4cDIoIHRoaXMuY29sb3IuZ2V0SGV4KCksIHRoaXMuZGVuc2l0eSApO1xuXG59O1xuXG5Gb2dFeHAyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoIG1ldGEgKSB7XG5cblx0cmV0dXJuIHtcblx0XHR0eXBlOiAnRm9nRXhwMicsXG5cdFx0Y29sb3I6IHRoaXMuY29sb3IuZ2V0SGV4KCksXG5cdFx0ZGVuc2l0eTogdGhpcy5kZW5zaXR5XG5cdH07XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gRm9nICggY29sb3IsIG5lYXIsIGZhciApIHtcblxuXHR0aGlzLm5hbWUgPSAnJztcblxuXHR0aGlzLmNvbG9yID0gbmV3IENvbG9yKCBjb2xvciApO1xuXG5cdHRoaXMubmVhciA9ICggbmVhciAhPT0gdW5kZWZpbmVkICkgPyBuZWFyIDogMTtcblx0dGhpcy5mYXIgPSAoIGZhciAhPT0gdW5kZWZpbmVkICkgPyBmYXIgOiAxMDAwO1xuXG59XG5cbkZvZy5wcm90b3R5cGUuaXNGb2cgPSB0cnVlO1xuXG5Gb2cucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuXG5cdHJldHVybiBuZXcgRm9nKCB0aGlzLmNvbG9yLmdldEhleCgpLCB0aGlzLm5lYXIsIHRoaXMuZmFyICk7XG5cbn07XG5cbkZvZy5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCBtZXRhICkge1xuXG5cdHJldHVybiB7XG5cdFx0dHlwZTogJ0ZvZycsXG5cdFx0Y29sb3I6IHRoaXMuY29sb3IuZ2V0SGV4KCksXG5cdFx0bmVhcjogdGhpcy5uZWFyLFxuXHRcdGZhcjogdGhpcy5mYXJcblx0fTtcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFNjZW5lICgpIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1NjZW5lJztcblxuXHR0aGlzLmJhY2tncm91bmQgPSBudWxsO1xuXHR0aGlzLmZvZyA9IG51bGw7XG5cdHRoaXMub3ZlcnJpZGVNYXRlcmlhbCA9IG51bGw7XG5cblx0dGhpcy5hdXRvVXBkYXRlID0gdHJ1ZTsgLy8gY2hlY2tlZCBieSB0aGUgcmVuZGVyZXJcblxufVxuXG5TY2VuZS5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBPYmplY3QzRC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBTY2VuZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSwgcmVjdXJzaXZlICkge1xuXG5cdFx0T2JqZWN0M0QucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlLCByZWN1cnNpdmUgKTtcblxuXHRcdGlmICggc291cmNlLmJhY2tncm91bmQgIT09IG51bGwgKSB0aGlzLmJhY2tncm91bmQgPSBzb3VyY2UuYmFja2dyb3VuZC5jbG9uZSgpO1xuXHRcdGlmICggc291cmNlLmZvZyAhPT0gbnVsbCApIHRoaXMuZm9nID0gc291cmNlLmZvZy5jbG9uZSgpO1xuXHRcdGlmICggc291cmNlLm92ZXJyaWRlTWF0ZXJpYWwgIT09IG51bGwgKSB0aGlzLm92ZXJyaWRlTWF0ZXJpYWwgPSBzb3VyY2Uub3ZlcnJpZGVNYXRlcmlhbC5jbG9uZSgpO1xuXG5cdFx0dGhpcy5hdXRvVXBkYXRlID0gc291cmNlLmF1dG9VcGRhdGU7XG5cdFx0dGhpcy5tYXRyaXhBdXRvVXBkYXRlID0gc291cmNlLm1hdHJpeEF1dG9VcGRhdGU7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCBtZXRhICkge1xuXG5cdFx0dmFyIGRhdGEgPSBPYmplY3QzRC5wcm90b3R5cGUudG9KU09OLmNhbGwoIHRoaXMsIG1ldGEgKTtcblxuXHRcdGlmICggdGhpcy5iYWNrZ3JvdW5kICE9PSBudWxsICkgZGF0YS5vYmplY3QuYmFja2dyb3VuZCA9IHRoaXMuYmFja2dyb3VuZC50b0pTT04oIG1ldGEgKTtcblx0XHRpZiAoIHRoaXMuZm9nICE9PSBudWxsICkgZGF0YS5vYmplY3QuZm9nID0gdGhpcy5mb2cudG9KU09OKCk7XG5cblx0XHRyZXR1cm4gZGF0YTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBMZW5zRmxhcmUoIHRleHR1cmUsIHNpemUsIGRpc3RhbmNlLCBibGVuZGluZywgY29sb3IgKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMubGVuc0ZsYXJlcyA9IFtdO1xuXG5cdHRoaXMucG9zaXRpb25TY3JlZW4gPSBuZXcgVmVjdG9yMygpO1xuXHR0aGlzLmN1c3RvbVVwZGF0ZUNhbGxiYWNrID0gdW5kZWZpbmVkO1xuXG5cdGlmICggdGV4dHVyZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0dGhpcy5hZGQoIHRleHR1cmUsIHNpemUsIGRpc3RhbmNlLCBibGVuZGluZywgY29sb3IgKTtcblxuXHR9XG5cbn1cblxuTGVuc0ZsYXJlLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IExlbnNGbGFyZSxcblxuXHRpc0xlbnNGbGFyZTogdHJ1ZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdE9iamVjdDNELnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdFx0dGhpcy5wb3NpdGlvblNjcmVlbi5jb3B5KCBzb3VyY2UucG9zaXRpb25TY3JlZW4gKTtcblx0XHR0aGlzLmN1c3RvbVVwZGF0ZUNhbGxiYWNrID0gc291cmNlLmN1c3RvbVVwZGF0ZUNhbGxiYWNrO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gc291cmNlLmxlbnNGbGFyZXMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dGhpcy5sZW5zRmxhcmVzLnB1c2goIHNvdXJjZS5sZW5zRmxhcmVzWyBpIF0gKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiAoIHRleHR1cmUsIHNpemUsIGRpc3RhbmNlLCBibGVuZGluZywgY29sb3IsIG9wYWNpdHkgKSB7XG5cblx0XHRpZiAoIHNpemUgPT09IHVuZGVmaW5lZCApIHNpemUgPSAtIDE7XG5cdFx0aWYgKCBkaXN0YW5jZSA9PT0gdW5kZWZpbmVkICkgZGlzdGFuY2UgPSAwO1xuXHRcdGlmICggb3BhY2l0eSA9PT0gdW5kZWZpbmVkICkgb3BhY2l0eSA9IDE7XG5cdFx0aWYgKCBjb2xvciA9PT0gdW5kZWZpbmVkICkgY29sb3IgPSBuZXcgQ29sb3IoIDB4ZmZmZmZmICk7XG5cdFx0aWYgKCBibGVuZGluZyA9PT0gdW5kZWZpbmVkICkgYmxlbmRpbmcgPSBOb3JtYWxCbGVuZGluZztcblxuXHRcdGRpc3RhbmNlID0gTWF0aC5taW4oIGRpc3RhbmNlLCBNYXRoLm1heCggMCwgZGlzdGFuY2UgKSApO1xuXG5cdFx0dGhpcy5sZW5zRmxhcmVzLnB1c2goIHtcblx0XHRcdHRleHR1cmU6IHRleHR1cmUsXHQvLyBUSFJFRS5UZXh0dXJlXG5cdFx0XHRzaXplOiBzaXplLCBcdFx0Ly8gc2l6ZSBpbiBwaXhlbHMgKC0xID0gdXNlIHRleHR1cmUud2lkdGgpXG5cdFx0XHRkaXN0YW5jZTogZGlzdGFuY2UsIFx0Ly8gZGlzdGFuY2UgKDAtMSkgZnJvbSBsaWdodCBzb3VyY2UgKDA9YXQgbGlnaHQgc291cmNlKVxuXHRcdFx0eDogMCwgeTogMCwgejogMCxcdC8vIHNjcmVlbiBwb3NpdGlvbiAoLTEgPT4gMSkgeiA9IDAgaXMgaW4gZnJvbnQgeiA9IDEgaXMgYmFja1xuXHRcdFx0c2NhbGU6IDEsIFx0XHQvLyBzY2FsZVxuXHRcdFx0cm90YXRpb246IDAsIFx0XHQvLyByb3RhdGlvblxuXHRcdFx0b3BhY2l0eTogb3BhY2l0eSxcdC8vIG9wYWNpdHlcblx0XHRcdGNvbG9yOiBjb2xvcixcdFx0Ly8gY29sb3Jcblx0XHRcdGJsZW5kaW5nOiBibGVuZGluZ1x0Ly8gYmxlbmRpbmdcblx0XHR9ICk7XG5cblx0fSxcblxuXHQvKlxuXHQgKiBVcGRhdGUgbGVucyBmbGFyZXMgdXBkYXRlIHBvc2l0aW9ucyBvbiBhbGwgZmxhcmVzIGJhc2VkIG9uIHRoZSBzY3JlZW4gcG9zaXRpb25cblx0ICogU2V0IG15TGVuc0ZsYXJlLmN1c3RvbVVwZGF0ZUNhbGxiYWNrIHRvIGFsdGVyIHRoZSBmbGFyZXMgaW4geW91ciBwcm9qZWN0IHNwZWNpZmljIHdheS5cblx0ICovXG5cblx0dXBkYXRlTGVuc0ZsYXJlczogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGYsIGZsID0gdGhpcy5sZW5zRmxhcmVzLmxlbmd0aDtcblx0XHR2YXIgZmxhcmU7XG5cdFx0dmFyIHZlY1ggPSAtIHRoaXMucG9zaXRpb25TY3JlZW4ueCAqIDI7XG5cdFx0dmFyIHZlY1kgPSAtIHRoaXMucG9zaXRpb25TY3JlZW4ueSAqIDI7XG5cblx0XHRmb3IgKCBmID0gMDsgZiA8IGZsOyBmICsrICkge1xuXG5cdFx0XHRmbGFyZSA9IHRoaXMubGVuc0ZsYXJlc1sgZiBdO1xuXG5cdFx0XHRmbGFyZS54ID0gdGhpcy5wb3NpdGlvblNjcmVlbi54ICsgdmVjWCAqIGZsYXJlLmRpc3RhbmNlO1xuXHRcdFx0ZmxhcmUueSA9IHRoaXMucG9zaXRpb25TY3JlZW4ueSArIHZlY1kgKiBmbGFyZS5kaXN0YW5jZTtcblxuXHRcdFx0ZmxhcmUud2FudGVkUm90YXRpb24gPSBmbGFyZS54ICogTWF0aC5QSSAqIDAuMjU7XG5cdFx0XHRmbGFyZS5yb3RhdGlvbiArPSAoIGZsYXJlLndhbnRlZFJvdGF0aW9uIC0gZmxhcmUucm90YXRpb24gKSAqIDAuMjU7XG5cblx0XHR9XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqXG4gKiBwYXJhbWV0ZXJzID0ge1xuICogIGNvbG9yOiA8aGV4PixcbiAqICBvcGFjaXR5OiA8ZmxvYXQ+LFxuICogIG1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKlx0dXZPZmZzZXQ6IG5ldyBUSFJFRS5WZWN0b3IyKCksXG4gKlx0dXZTY2FsZTogbmV3IFRIUkVFLlZlY3RvcjIoKVxuICogfVxuICovXG5cbmZ1bmN0aW9uIFNwcml0ZU1hdGVyaWFsKCBwYXJhbWV0ZXJzICkge1xuXG5cdE1hdGVyaWFsLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnU3ByaXRlTWF0ZXJpYWwnO1xuXG5cdHRoaXMuY29sb3IgPSBuZXcgQ29sb3IoIDB4ZmZmZmZmICk7XG5cdHRoaXMubWFwID0gbnVsbDtcblxuXHR0aGlzLnJvdGF0aW9uID0gMDtcblxuXHR0aGlzLmZvZyA9IGZhbHNlO1xuXHR0aGlzLmxpZ2h0cyA9IGZhbHNlO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuU3ByaXRlTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWF0ZXJpYWwucHJvdG90eXBlICk7XG5TcHJpdGVNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBTcHJpdGVNYXRlcmlhbDtcblNwcml0ZU1hdGVyaWFsLnByb3RvdHlwZS5pc1Nwcml0ZU1hdGVyaWFsID0gdHJ1ZTtcblxuU3ByaXRlTWF0ZXJpYWwucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRNYXRlcmlhbC5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHR0aGlzLmNvbG9yLmNvcHkoIHNvdXJjZS5jb2xvciApO1xuXHR0aGlzLm1hcCA9IHNvdXJjZS5tYXA7XG5cblx0dGhpcy5yb3RhdGlvbiA9IHNvdXJjZS5yb3RhdGlvbjtcblxuXHRyZXR1cm4gdGhpcztcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBTcHJpdGUoIG1hdGVyaWFsICkge1xuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnU3ByaXRlJztcblxuXHR0aGlzLm1hdGVyaWFsID0gKCBtYXRlcmlhbCAhPT0gdW5kZWZpbmVkICkgPyBtYXRlcmlhbCA6IG5ldyBTcHJpdGVNYXRlcmlhbCgpO1xuXG59XG5cblNwcml0ZS5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBPYmplY3QzRC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBTcHJpdGUsXG5cblx0aXNTcHJpdGU6IHRydWUsXG5cblx0cmF5Y2FzdDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgaW50ZXJzZWN0UG9pbnQgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB3b3JsZFBvc2l0aW9uID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgd29ybGRTY2FsZSA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcmF5Y2FzdCggcmF5Y2FzdGVyLCBpbnRlcnNlY3RzICkge1xuXG5cdFx0XHR3b3JsZFBvc2l0aW9uLnNldEZyb21NYXRyaXhQb3NpdGlvbiggdGhpcy5tYXRyaXhXb3JsZCApO1xuXHRcdFx0cmF5Y2FzdGVyLnJheS5jbG9zZXN0UG9pbnRUb1BvaW50KCB3b3JsZFBvc2l0aW9uLCBpbnRlcnNlY3RQb2ludCApO1xuXG5cdFx0XHR3b3JsZFNjYWxlLnNldEZyb21NYXRyaXhTY2FsZSggdGhpcy5tYXRyaXhXb3JsZCApO1xuXHRcdFx0dmFyIGd1ZXNzU2l6ZVNxID0gd29ybGRTY2FsZS54ICogd29ybGRTY2FsZS55IC8gNDtcblxuXHRcdFx0aWYgKCB3b3JsZFBvc2l0aW9uLmRpc3RhbmNlVG9TcXVhcmVkKCBpbnRlcnNlY3RQb2ludCApID4gZ3Vlc3NTaXplU3EgKSByZXR1cm47XG5cblx0XHRcdHZhciBkaXN0YW5jZSA9IHJheWNhc3Rlci5yYXkub3JpZ2luLmRpc3RhbmNlVG8oIGludGVyc2VjdFBvaW50ICk7XG5cblx0XHRcdGlmICggZGlzdGFuY2UgPCByYXljYXN0ZXIubmVhciB8fCBkaXN0YW5jZSA+IHJheWNhc3Rlci5mYXIgKSByZXR1cm47XG5cblx0XHRcdGludGVyc2VjdHMucHVzaCgge1xuXG5cdFx0XHRcdGRpc3RhbmNlOiBkaXN0YW5jZSxcblx0XHRcdFx0cG9pbnQ6IGludGVyc2VjdFBvaW50LmNsb25lKCksXG5cdFx0XHRcdGZhY2U6IG51bGwsXG5cdFx0XHRcdG9iamVjdDogdGhpc1xuXG5cdFx0XHR9ICk7XG5cblx0XHR9O1xuXG5cdH0oKSApLFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoIHRoaXMubWF0ZXJpYWwgKS5jb3B5KCB0aGlzICk7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIExPRCgpIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0xPRCc7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIHRoaXMsIHtcblx0XHRsZXZlbHM6IHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHR2YWx1ZTogW11cblx0XHR9XG5cdH0gKTtcblxufVxuXG5MT0QucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTE9ELFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0T2JqZWN0M0QucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlLCBmYWxzZSApO1xuXG5cdFx0dmFyIGxldmVscyA9IHNvdXJjZS5sZXZlbHM7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBsZXZlbHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGxldmVsID0gbGV2ZWxzWyBpIF07XG5cblx0XHRcdHRoaXMuYWRkTGV2ZWwoIGxldmVsLm9iamVjdC5jbG9uZSgpLCBsZXZlbC5kaXN0YW5jZSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRhZGRMZXZlbDogZnVuY3Rpb24gKCBvYmplY3QsIGRpc3RhbmNlICkge1xuXG5cdFx0aWYgKCBkaXN0YW5jZSA9PT0gdW5kZWZpbmVkICkgZGlzdGFuY2UgPSAwO1xuXG5cdFx0ZGlzdGFuY2UgPSBNYXRoLmFicyggZGlzdGFuY2UgKTtcblxuXHRcdHZhciBsZXZlbHMgPSB0aGlzLmxldmVscztcblxuXHRcdGZvciAoIHZhciBsID0gMDsgbCA8IGxldmVscy5sZW5ndGg7IGwgKysgKSB7XG5cblx0XHRcdGlmICggZGlzdGFuY2UgPCBsZXZlbHNbIGwgXS5kaXN0YW5jZSApIHtcblxuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0bGV2ZWxzLnNwbGljZSggbCwgMCwgeyBkaXN0YW5jZTogZGlzdGFuY2UsIG9iamVjdDogb2JqZWN0IH0gKTtcblxuXHRcdHRoaXMuYWRkKCBvYmplY3QgKTtcblxuXHR9LFxuXG5cdGdldE9iamVjdEZvckRpc3RhbmNlOiBmdW5jdGlvbiAoIGRpc3RhbmNlICkge1xuXG5cdFx0dmFyIGxldmVscyA9IHRoaXMubGV2ZWxzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAxLCBsID0gbGV2ZWxzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdGlmICggZGlzdGFuY2UgPCBsZXZlbHNbIGkgXS5kaXN0YW5jZSApIHtcblxuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGxldmVsc1sgaSAtIDEgXS5vYmplY3Q7XG5cblx0fSxcblxuXHRyYXljYXN0OiAoIGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBtYXRyaXhQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gcmF5Y2FzdCggcmF5Y2FzdGVyLCBpbnRlcnNlY3RzICkge1xuXG5cdFx0XHRtYXRyaXhQb3NpdGlvbi5zZXRGcm9tTWF0cml4UG9zaXRpb24oIHRoaXMubWF0cml4V29ybGQgKTtcblxuXHRcdFx0dmFyIGRpc3RhbmNlID0gcmF5Y2FzdGVyLnJheS5vcmlnaW4uZGlzdGFuY2VUbyggbWF0cml4UG9zaXRpb24gKTtcblxuXHRcdFx0dGhpcy5nZXRPYmplY3RGb3JEaXN0YW5jZSggZGlzdGFuY2UgKS5yYXljYXN0KCByYXljYXN0ZXIsIGludGVyc2VjdHMgKTtcblxuXHRcdH07XG5cblx0fSgpICksXG5cblx0dXBkYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciB2MiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCBjYW1lcmEgKSB7XG5cblx0XHRcdHZhciBsZXZlbHMgPSB0aGlzLmxldmVscztcblxuXHRcdFx0aWYgKCBsZXZlbHMubGVuZ3RoID4gMSApIHtcblxuXHRcdFx0XHR2MS5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGNhbWVyYS5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHR2Mi5zZXRGcm9tTWF0cml4UG9zaXRpb24oIHRoaXMubWF0cml4V29ybGQgKTtcblxuXHRcdFx0XHR2YXIgZGlzdGFuY2UgPSB2MS5kaXN0YW5jZVRvKCB2MiApO1xuXG5cdFx0XHRcdGxldmVsc1sgMCBdLm9iamVjdC52aXNpYmxlID0gdHJ1ZTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDEsIGwgPSBsZXZlbHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRcdGlmICggZGlzdGFuY2UgPj0gbGV2ZWxzWyBpIF0uZGlzdGFuY2UgKSB7XG5cblx0XHRcdFx0XHRcdGxldmVsc1sgaSAtIDEgXS5vYmplY3QudmlzaWJsZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0bGV2ZWxzWyBpIF0ub2JqZWN0LnZpc2libGUgPSB0cnVlO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRsZXZlbHNbIGkgXS5vYmplY3QudmlzaWJsZSA9IGZhbHNlO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHR9KCksXG5cblx0dG9KU09OOiBmdW5jdGlvbiAoIG1ldGEgKSB7XG5cblx0XHR2YXIgZGF0YSA9IE9iamVjdDNELnByb3RvdHlwZS50b0pTT04uY2FsbCggdGhpcywgbWV0YSApO1xuXG5cdFx0ZGF0YS5vYmplY3QubGV2ZWxzID0gW107XG5cblx0XHR2YXIgbGV2ZWxzID0gdGhpcy5sZXZlbHM7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBsZXZlbHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGxldmVsID0gbGV2ZWxzWyBpIF07XG5cblx0XHRcdGRhdGEub2JqZWN0LmxldmVscy5wdXNoKCB7XG5cdFx0XHRcdG9iamVjdDogbGV2ZWwub2JqZWN0LnV1aWQsXG5cdFx0XHRcdGRpc3RhbmNlOiBsZXZlbC5kaXN0YW5jZVxuXHRcdFx0fSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRhdGE7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtaWthZWwgZW10aW5nZXIgLyBodHRwOi8vZ29tby5zZS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIG1pY2hhZWwgZ3VlcnJlcm8gLyBodHRwOi8vcmVhbGl0eW1lbHRkb3duLmNvbVxuICogQGF1dGhvciBpa2VyciAvIGh0dHA6Ly92ZXJvbGQuY29tXG4gKi9cblxuZnVuY3Rpb24gU2tlbGV0b24oIGJvbmVzLCBib25lSW52ZXJzZXMgKSB7XG5cblx0Ly8gY29weSB0aGUgYm9uZSBhcnJheVxuXG5cdGJvbmVzID0gYm9uZXMgfHwgW107XG5cblx0dGhpcy5ib25lcyA9IGJvbmVzLnNsaWNlKCAwICk7XG5cdHRoaXMuYm9uZU1hdHJpY2VzID0gbmV3IEZsb2F0MzJBcnJheSggdGhpcy5ib25lcy5sZW5ndGggKiAxNiApO1xuXG5cdC8vIHVzZSB0aGUgc3VwcGxpZWQgYm9uZSBpbnZlcnNlcyBvciBjYWxjdWxhdGUgdGhlIGludmVyc2VzXG5cblx0aWYgKCBib25lSW52ZXJzZXMgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdHRoaXMuY2FsY3VsYXRlSW52ZXJzZXMoKTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0aWYgKCB0aGlzLmJvbmVzLmxlbmd0aCA9PT0gYm9uZUludmVyc2VzLmxlbmd0aCApIHtcblxuXHRcdFx0dGhpcy5ib25lSW52ZXJzZXMgPSBib25lSW52ZXJzZXMuc2xpY2UoIDAgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlNrZWxldG9uIGJvbmVJbnZlcnNlcyBpcyB0aGUgd3JvbmcgbGVuZ3RoLicgKTtcblxuXHRcdFx0dGhpcy5ib25lSW52ZXJzZXMgPSBbXTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHRoaXMuYm9uZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0dGhpcy5ib25lSW52ZXJzZXMucHVzaCggbmV3IE1hdHJpeDQoKSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fVxuXG59XG5cbk9iamVjdC5hc3NpZ24oIFNrZWxldG9uLnByb3RvdHlwZSwge1xuXG5cdGNhbGN1bGF0ZUludmVyc2VzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLmJvbmVJbnZlcnNlcyA9IFtdO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHRoaXMuYm9uZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBpbnZlcnNlID0gbmV3IE1hdHJpeDQoKTtcblxuXHRcdFx0aWYgKCB0aGlzLmJvbmVzWyBpIF0gKSB7XG5cblx0XHRcdFx0aW52ZXJzZS5nZXRJbnZlcnNlKCB0aGlzLmJvbmVzWyBpIF0ubWF0cml4V29ybGQgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmJvbmVJbnZlcnNlcy5wdXNoKCBpbnZlcnNlICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRwb3NlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYm9uZSwgaSwgaWw7XG5cblx0XHQvLyByZWNvdmVyIHRoZSBiaW5kLXRpbWUgd29ybGQgbWF0cmljZXNcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IHRoaXMuYm9uZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdGJvbmUgPSB0aGlzLmJvbmVzWyBpIF07XG5cblx0XHRcdGlmICggYm9uZSApIHtcblxuXHRcdFx0XHRib25lLm1hdHJpeFdvcmxkLmdldEludmVyc2UoIHRoaXMuYm9uZUludmVyc2VzWyBpIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gY29tcHV0ZSB0aGUgbG9jYWwgbWF0cmljZXMsIHBvc2l0aW9ucywgcm90YXRpb25zIGFuZCBzY2FsZXNcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IHRoaXMuYm9uZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdGJvbmUgPSB0aGlzLmJvbmVzWyBpIF07XG5cblx0XHRcdGlmICggYm9uZSApIHtcblxuXHRcdFx0XHRpZiAoIGJvbmUucGFyZW50ICYmIGJvbmUucGFyZW50LmlzQm9uZSApIHtcblxuXHRcdFx0XHRcdGJvbmUubWF0cml4LmdldEludmVyc2UoIGJvbmUucGFyZW50Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdFx0Ym9uZS5tYXRyaXgubXVsdGlwbHkoIGJvbmUubWF0cml4V29ybGQgKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Ym9uZS5tYXRyaXguY29weSggYm9uZS5tYXRyaXhXb3JsZCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRib25lLm1hdHJpeC5kZWNvbXBvc2UoIGJvbmUucG9zaXRpb24sIGJvbmUucXVhdGVybmlvbiwgYm9uZS5zY2FsZSApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fSxcblxuXHR1cGRhdGU6ICggZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIG9mZnNldE1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0dmFyIGlkZW50aXR5TWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiB1cGRhdGUoKSB7XG5cblx0XHRcdHZhciBib25lcyA9IHRoaXMuYm9uZXM7XG5cdFx0XHR2YXIgYm9uZUludmVyc2VzID0gdGhpcy5ib25lSW52ZXJzZXM7XG5cdFx0XHR2YXIgYm9uZU1hdHJpY2VzID0gdGhpcy5ib25lTWF0cmljZXM7XG5cdFx0XHR2YXIgYm9uZVRleHR1cmUgPSB0aGlzLmJvbmVUZXh0dXJlO1xuXG5cdFx0XHQvLyBmbGF0dGVuIGJvbmUgbWF0cmljZXMgdG8gYXJyYXlcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IGJvbmVzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHRcdC8vIGNvbXB1dGUgdGhlIG9mZnNldCBiZXR3ZWVuIHRoZSBjdXJyZW50IGFuZCB0aGUgb3JpZ2luYWwgdHJhbnNmb3JtXG5cblx0XHRcdFx0dmFyIG1hdHJpeCA9IGJvbmVzWyBpIF0gPyBib25lc1sgaSBdLm1hdHJpeFdvcmxkIDogaWRlbnRpdHlNYXRyaXg7XG5cblx0XHRcdFx0b2Zmc2V0TWF0cml4Lm11bHRpcGx5TWF0cmljZXMoIG1hdHJpeCwgYm9uZUludmVyc2VzWyBpIF0gKTtcblx0XHRcdFx0b2Zmc2V0TWF0cml4LnRvQXJyYXkoIGJvbmVNYXRyaWNlcywgaSAqIDE2ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBib25lVGV4dHVyZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGJvbmVUZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHR9ICkoKSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyBTa2VsZXRvbiggdGhpcy5ib25lcywgdGhpcy5ib25lSW52ZXJzZXMgKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgaWtlcnIgLyBodHRwOi8vdmVyb2xkLmNvbVxuICovXG5cbmZ1bmN0aW9uIEJvbmUoKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdCb25lJztcblxufVxuXG5Cb25lLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IEJvbmUsXG5cblx0aXNCb25lOiB0cnVlXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1pa2FlbCBlbXRpbmdlciAvIGh0dHA6Ly9nb21vLnNlL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgaWtlcnIgLyBodHRwOi8vdmVyb2xkLmNvbVxuICovXG5cbmZ1bmN0aW9uIFNraW5uZWRNZXNoKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSB7XG5cblx0TWVzaC5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcblxuXHR0aGlzLnR5cGUgPSAnU2tpbm5lZE1lc2gnO1xuXG5cdHRoaXMuYmluZE1vZGUgPSAnYXR0YWNoZWQnO1xuXHR0aGlzLmJpbmRNYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXHR0aGlzLmJpbmRNYXRyaXhJbnZlcnNlID0gbmV3IE1hdHJpeDQoKTtcblxuXHR2YXIgYm9uZXMgPSB0aGlzLmluaXRCb25lcygpO1xuXHR2YXIgc2tlbGV0b24gPSBuZXcgU2tlbGV0b24oIGJvbmVzICk7XG5cblx0dGhpcy5iaW5kKCBza2VsZXRvbiwgdGhpcy5tYXRyaXhXb3JsZCApO1xuXG5cdHRoaXMubm9ybWFsaXplU2tpbldlaWdodHMoKTtcblxufVxuXG5Ta2lubmVkTWVzaC5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBNZXNoLnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IFNraW5uZWRNZXNoLFxuXG5cdGlzU2tpbm5lZE1lc2g6IHRydWUsXG5cblx0aW5pdEJvbmVzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYm9uZXMgPSBbXSwgYm9uZSwgZ2JvbmU7XG5cdFx0dmFyIGksIGlsO1xuXG5cdFx0aWYgKCB0aGlzLmdlb21ldHJ5ICYmIHRoaXMuZ2VvbWV0cnkuYm9uZXMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gZmlyc3QsIGNyZWF0ZSBhcnJheSBvZiAnQm9uZScgb2JqZWN0cyBmcm9tIGdlb21ldHJ5IGRhdGFcblxuXHRcdFx0Zm9yICggaSA9IDAsIGlsID0gdGhpcy5nZW9tZXRyeS5ib25lcy5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0XHRnYm9uZSA9IHRoaXMuZ2VvbWV0cnkuYm9uZXNbIGkgXTtcblxuXHRcdFx0XHQvLyBjcmVhdGUgbmV3ICdCb25lJyBvYmplY3RcblxuXHRcdFx0XHRib25lID0gbmV3IEJvbmUoKTtcblx0XHRcdFx0Ym9uZXMucHVzaCggYm9uZSApO1xuXG5cdFx0XHRcdC8vIGFwcGx5IHZhbHVlc1xuXG5cdFx0XHRcdGJvbmUubmFtZSA9IGdib25lLm5hbWU7XG5cdFx0XHRcdGJvbmUucG9zaXRpb24uZnJvbUFycmF5KCBnYm9uZS5wb3MgKTtcblx0XHRcdFx0Ym9uZS5xdWF0ZXJuaW9uLmZyb21BcnJheSggZ2JvbmUucm90cSApO1xuXHRcdFx0XHRpZiAoIGdib25lLnNjbCAhPT0gdW5kZWZpbmVkICkgYm9uZS5zY2FsZS5mcm9tQXJyYXkoIGdib25lLnNjbCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIHNlY29uZCwgY3JlYXRlIGJvbmUgaGllcmFyY2h5XG5cblx0XHRcdGZvciAoIGkgPSAwLCBpbCA9IHRoaXMuZ2VvbWV0cnkuYm9uZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0Z2JvbmUgPSB0aGlzLmdlb21ldHJ5LmJvbmVzWyBpIF07XG5cblx0XHRcdFx0aWYgKCAoIGdib25lLnBhcmVudCAhPT0gLSAxICkgJiYgKCBnYm9uZS5wYXJlbnQgIT09IG51bGwgKSAmJiAoIGJvbmVzWyBnYm9uZS5wYXJlbnQgXSAhPT0gdW5kZWZpbmVkICkgKSB7XG5cblx0XHRcdFx0XHQvLyBzdWJzZXF1ZW50IGJvbmVzIGluIHRoZSBoaWVyYXJjaHlcblxuXHRcdFx0XHRcdGJvbmVzWyBnYm9uZS5wYXJlbnQgXS5hZGQoIGJvbmVzWyBpIF0gKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Ly8gdG9wbW9zdCBib25lLCBpbW1lZGlhdGUgY2hpbGQgb2YgdGhlIHNraW5uZWQgbWVzaFxuXG5cdFx0XHRcdFx0dGhpcy5hZGQoIGJvbmVzWyBpIF0gKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdC8vIG5vdyB0aGUgYm9uZXMgYXJlIHBhcnQgb2YgdGhlIHNjZW5lIGdyYXBoIGFuZCBjaGlsZHJlbiBvZiB0aGUgc2tpbm5lZCBtZXNoLlxuXHRcdC8vIGxldCdzIHVwZGF0ZSB0aGUgY29ycmVzcG9uZGluZyBtYXRyaWNlc1xuXG5cdFx0dGhpcy51cGRhdGVNYXRyaXhXb3JsZCggdHJ1ZSApO1xuXG5cdFx0cmV0dXJuIGJvbmVzO1xuXG5cdH0sXG5cblx0YmluZDogZnVuY3Rpb24gKCBza2VsZXRvbiwgYmluZE1hdHJpeCApIHtcblxuXHRcdHRoaXMuc2tlbGV0b24gPSBza2VsZXRvbjtcblxuXHRcdGlmICggYmluZE1hdHJpeCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR0aGlzLnVwZGF0ZU1hdHJpeFdvcmxkKCB0cnVlICk7XG5cblx0XHRcdHRoaXMuc2tlbGV0b24uY2FsY3VsYXRlSW52ZXJzZXMoKTtcblxuXHRcdFx0YmluZE1hdHJpeCA9IHRoaXMubWF0cml4V29ybGQ7XG5cblx0XHR9XG5cblx0XHR0aGlzLmJpbmRNYXRyaXguY29weSggYmluZE1hdHJpeCApO1xuXHRcdHRoaXMuYmluZE1hdHJpeEludmVyc2UuZ2V0SW52ZXJzZSggYmluZE1hdHJpeCApO1xuXG5cdH0sXG5cblx0cG9zZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5za2VsZXRvbi5wb3NlKCk7XG5cblx0fSxcblxuXHRub3JtYWxpemVTa2luV2VpZ2h0czogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHNjYWxlLCBpO1xuXG5cdFx0aWYgKCB0aGlzLmdlb21ldHJ5ICYmIHRoaXMuZ2VvbWV0cnkuaXNHZW9tZXRyeSApIHtcblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCB0aGlzLmdlb21ldHJ5LnNraW5XZWlnaHRzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHR2YXIgc3cgPSB0aGlzLmdlb21ldHJ5LnNraW5XZWlnaHRzWyBpIF07XG5cblx0XHRcdFx0c2NhbGUgPSAxLjAgLyBzdy5sZW5ndGhNYW5oYXR0YW4oKTtcblxuXHRcdFx0XHRpZiAoIHNjYWxlICE9PSBJbmZpbml0eSApIHtcblxuXHRcdFx0XHRcdHN3Lm11bHRpcGx5U2NhbGFyKCBzY2FsZSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRzdy5zZXQoIDEsIDAsIDAsIDAgKTsgLy8gZG8gc29tZXRoaW5nIHJlYXNvbmFibGVcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSBpZiAoIHRoaXMuZ2VvbWV0cnkgJiYgdGhpcy5nZW9tZXRyeS5pc0J1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHR2YXIgdmVjID0gbmV3IFZlY3RvcjQoKTtcblxuXHRcdFx0dmFyIHNraW5XZWlnaHQgPSB0aGlzLmdlb21ldHJ5LmF0dHJpYnV0ZXMuc2tpbldlaWdodDtcblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBza2luV2VpZ2h0LmNvdW50OyBpICsrICkge1xuXG5cdFx0XHRcdHZlYy54ID0gc2tpbldlaWdodC5nZXRYKCBpICk7XG5cdFx0XHRcdHZlYy55ID0gc2tpbldlaWdodC5nZXRZKCBpICk7XG5cdFx0XHRcdHZlYy56ID0gc2tpbldlaWdodC5nZXRaKCBpICk7XG5cdFx0XHRcdHZlYy53ID0gc2tpbldlaWdodC5nZXRXKCBpICk7XG5cblx0XHRcdFx0c2NhbGUgPSAxLjAgLyB2ZWMubGVuZ3RoTWFuaGF0dGFuKCk7XG5cblx0XHRcdFx0aWYgKCBzY2FsZSAhPT0gSW5maW5pdHkgKSB7XG5cblx0XHRcdFx0XHR2ZWMubXVsdGlwbHlTY2FsYXIoIHNjYWxlICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHZlYy5zZXQoIDEsIDAsIDAsIDAgKTsgLy8gZG8gc29tZXRoaW5nIHJlYXNvbmFibGVcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2tpbldlaWdodC5zZXRYWVpXKCBpLCB2ZWMueCwgdmVjLnksIHZlYy56LCB2ZWMudyApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fSxcblxuXHR1cGRhdGVNYXRyaXhXb3JsZDogZnVuY3Rpb24gKCBmb3JjZSApIHtcblxuXHRcdE1lc2gucHJvdG90eXBlLnVwZGF0ZU1hdHJpeFdvcmxkLmNhbGwoIHRoaXMsIGZvcmNlICk7XG5cblx0XHRpZiAoIHRoaXMuYmluZE1vZGUgPT09ICdhdHRhY2hlZCcgKSB7XG5cblx0XHRcdHRoaXMuYmluZE1hdHJpeEludmVyc2UuZ2V0SW52ZXJzZSggdGhpcy5tYXRyaXhXb3JsZCApO1xuXG5cdFx0fSBlbHNlIGlmICggdGhpcy5iaW5kTW9kZSA9PT0gJ2RldGFjaGVkJyApIHtcblxuXHRcdFx0dGhpcy5iaW5kTWF0cml4SW52ZXJzZS5nZXRJbnZlcnNlKCB0aGlzLmJpbmRNYXRyaXggKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlNraW5uZWRNZXNoOiBVbnJlY29nbml6ZWQgYmluZE1vZGU6ICcgKyB0aGlzLmJpbmRNb2RlICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCB0aGlzLmdlb21ldHJ5LCB0aGlzLm1hdGVyaWFsICkuY29weSggdGhpcyApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICpcbiAqIHBhcmFtZXRlcnMgPSB7XG4gKiAgY29sb3I6IDxoZXg+LFxuICogIG9wYWNpdHk6IDxmbG9hdD4sXG4gKlxuICogIGxpbmV3aWR0aDogPGZsb2F0PixcbiAqICBsaW5lY2FwOiBcInJvdW5kXCIsXG4gKiAgbGluZWpvaW46IFwicm91bmRcIlxuICogfVxuICovXG5cbmZ1bmN0aW9uIExpbmVCYXNpY01hdGVyaWFsKCBwYXJhbWV0ZXJzICkge1xuXG5cdE1hdGVyaWFsLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnTGluZUJhc2ljTWF0ZXJpYWwnO1xuXG5cdHRoaXMuY29sb3IgPSBuZXcgQ29sb3IoIDB4ZmZmZmZmICk7XG5cblx0dGhpcy5saW5ld2lkdGggPSAxO1xuXHR0aGlzLmxpbmVjYXAgPSAncm91bmQnO1xuXHR0aGlzLmxpbmVqb2luID0gJ3JvdW5kJztcblxuXHR0aGlzLmxpZ2h0cyA9IGZhbHNlO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuTGluZUJhc2ljTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWF0ZXJpYWwucHJvdG90eXBlICk7XG5MaW5lQmFzaWNNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMaW5lQmFzaWNNYXRlcmlhbDtcblxuTGluZUJhc2ljTWF0ZXJpYWwucHJvdG90eXBlLmlzTGluZUJhc2ljTWF0ZXJpYWwgPSB0cnVlO1xuXG5MaW5lQmFzaWNNYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuY29sb3IuY29weSggc291cmNlLmNvbG9yICk7XG5cblx0dGhpcy5saW5ld2lkdGggPSBzb3VyY2UubGluZXdpZHRoO1xuXHR0aGlzLmxpbmVjYXAgPSBzb3VyY2UubGluZWNhcDtcblx0dGhpcy5saW5lam9pbiA9IHNvdXJjZS5saW5lam9pbjtcblxuXHRyZXR1cm4gdGhpcztcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIExpbmUoIGdlb21ldHJ5LCBtYXRlcmlhbCwgbW9kZSApIHtcblxuXHRpZiAoIG1vZGUgPT09IDEgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaW5lOiBwYXJhbWV0ZXIgVEhSRUUuTGluZVBpZWNlcyBubyBsb25nZXIgc3VwcG9ydGVkLiBDcmVhdGVkIFRIUkVFLkxpbmVTZWdtZW50cyBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gbmV3IExpbmVTZWdtZW50cyggZ2VvbWV0cnksIG1hdGVyaWFsICk7XG5cblx0fVxuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnTGluZSc7XG5cblx0dGhpcy5nZW9tZXRyeSA9IGdlb21ldHJ5ICE9PSB1bmRlZmluZWQgPyBnZW9tZXRyeSA6IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXHR0aGlzLm1hdGVyaWFsID0gbWF0ZXJpYWwgIT09IHVuZGVmaW5lZCA/IG1hdGVyaWFsIDogbmV3IExpbmVCYXNpY01hdGVyaWFsKCB7IGNvbG9yOiBNYXRoLnJhbmRvbSgpICogMHhmZmZmZmYgfSApO1xuXG59XG5cbkxpbmUucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTGluZSxcblxuXHRpc0xpbmU6IHRydWUsXG5cblx0cmF5Y2FzdDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgaW52ZXJzZU1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0dmFyIHJheSA9IG5ldyBSYXkoKTtcblx0XHR2YXIgc3BoZXJlID0gbmV3IFNwaGVyZSgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHJheWNhc3QoIHJheWNhc3RlciwgaW50ZXJzZWN0cyApIHtcblxuXHRcdFx0dmFyIHByZWNpc2lvbiA9IHJheWNhc3Rlci5saW5lUHJlY2lzaW9uO1xuXHRcdFx0dmFyIHByZWNpc2lvblNxID0gcHJlY2lzaW9uICogcHJlY2lzaW9uO1xuXG5cdFx0XHR2YXIgZ2VvbWV0cnkgPSB0aGlzLmdlb21ldHJ5O1xuXHRcdFx0dmFyIG1hdHJpeFdvcmxkID0gdGhpcy5tYXRyaXhXb3JsZDtcblxuXHRcdFx0Ly8gQ2hlY2tpbmcgYm91bmRpbmdTcGhlcmUgZGlzdGFuY2UgdG8gcmF5XG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUgPT09IG51bGwgKSBnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTtcblxuXHRcdFx0c3BoZXJlLmNvcHkoIGdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlICk7XG5cdFx0XHRzcGhlcmUuYXBwbHlNYXRyaXg0KCBtYXRyaXhXb3JsZCApO1xuXG5cdFx0XHRpZiAoIHJheWNhc3Rlci5yYXkuaW50ZXJzZWN0c1NwaGVyZSggc3BoZXJlICkgPT09IGZhbHNlICkgcmV0dXJuO1xuXG5cdFx0XHQvL1xuXG5cdFx0XHRpbnZlcnNlTWF0cml4LmdldEludmVyc2UoIG1hdHJpeFdvcmxkICk7XG5cdFx0XHRyYXkuY29weSggcmF5Y2FzdGVyLnJheSApLmFwcGx5TWF0cml4NCggaW52ZXJzZU1hdHJpeCApO1xuXG5cdFx0XHR2YXIgdlN0YXJ0ID0gbmV3IFZlY3RvcjMoKTtcblx0XHRcdHZhciB2RW5kID0gbmV3IFZlY3RvcjMoKTtcblx0XHRcdHZhciBpbnRlclNlZ21lbnQgPSBuZXcgVmVjdG9yMygpO1xuXHRcdFx0dmFyIGludGVyUmF5ID0gbmV3IFZlY3RvcjMoKTtcblx0XHRcdHZhciBzdGVwID0gKHRoaXMgJiYgdGhpcy5pc0xpbmVTZWdtZW50cykgPyAyIDogMTtcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5pc0J1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHRcdHZhciBpbmRleCA9IGdlb21ldHJ5LmluZGV4O1xuXHRcdFx0XHR2YXIgYXR0cmlidXRlcyA9IGdlb21ldHJ5LmF0dHJpYnV0ZXM7XG5cdFx0XHRcdHZhciBwb3NpdGlvbnMgPSBhdHRyaWJ1dGVzLnBvc2l0aW9uLmFycmF5O1xuXG5cdFx0XHRcdGlmICggaW5kZXggIT09IG51bGwgKSB7XG5cblx0XHRcdFx0XHR2YXIgaW5kaWNlcyA9IGluZGV4LmFycmF5O1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gaW5kaWNlcy5sZW5ndGggLSAxOyBpIDwgbDsgaSArPSBzdGVwICkge1xuXG5cdFx0XHRcdFx0XHR2YXIgYSA9IGluZGljZXNbIGkgXTtcblx0XHRcdFx0XHRcdHZhciBiID0gaW5kaWNlc1sgaSArIDEgXTtcblxuXHRcdFx0XHRcdFx0dlN0YXJ0LmZyb21BcnJheSggcG9zaXRpb25zLCBhICogMyApO1xuXHRcdFx0XHRcdFx0dkVuZC5mcm9tQXJyYXkoIHBvc2l0aW9ucywgYiAqIDMgKTtcblxuXHRcdFx0XHRcdFx0dmFyIGRpc3RTcSA9IHJheS5kaXN0YW5jZVNxVG9TZWdtZW50KCB2U3RhcnQsIHZFbmQsIGludGVyUmF5LCBpbnRlclNlZ21lbnQgKTtcblxuXHRcdFx0XHRcdFx0aWYgKCBkaXN0U3EgPiBwcmVjaXNpb25TcSApIGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0XHRpbnRlclJheS5hcHBseU1hdHJpeDQoIHRoaXMubWF0cml4V29ybGQgKTsgLy9Nb3ZlIGJhY2sgdG8gd29ybGQgc3BhY2UgZm9yIGRpc3RhbmNlIGNhbGN1bGF0aW9uXG5cblx0XHRcdFx0XHRcdHZhciBkaXN0YW5jZSA9IHJheWNhc3Rlci5yYXkub3JpZ2luLmRpc3RhbmNlVG8oIGludGVyUmF5ICk7XG5cblx0XHRcdFx0XHRcdGlmICggZGlzdGFuY2UgPCByYXljYXN0ZXIubmVhciB8fCBkaXN0YW5jZSA+IHJheWNhc3Rlci5mYXIgKSBjb250aW51ZTtcblxuXHRcdFx0XHRcdFx0aW50ZXJzZWN0cy5wdXNoKCB7XG5cblx0XHRcdFx0XHRcdFx0ZGlzdGFuY2U6IGRpc3RhbmNlLFxuXHRcdFx0XHRcdFx0XHQvLyBXaGF0IGRvIHdlIHdhbnQ/IGludGVyc2VjdGlvbiBwb2ludCBvbiB0aGUgcmF5IG9yIG9uIHRoZSBzZWdtZW50Pz9cblx0XHRcdFx0XHRcdFx0Ly8gcG9pbnQ6IHJheWNhc3Rlci5yYXkuYXQoIGRpc3RhbmNlICksXG5cdFx0XHRcdFx0XHRcdHBvaW50OiBpbnRlclNlZ21lbnQuY2xvbmUoKS5hcHBseU1hdHJpeDQoIHRoaXMubWF0cml4V29ybGQgKSxcblx0XHRcdFx0XHRcdFx0aW5kZXg6IGksXG5cdFx0XHRcdFx0XHRcdGZhY2U6IG51bGwsXG5cdFx0XHRcdFx0XHRcdGZhY2VJbmRleDogbnVsbCxcblx0XHRcdFx0XHRcdFx0b2JqZWN0OiB0aGlzXG5cblx0XHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gcG9zaXRpb25zLmxlbmd0aCAvIDMgLSAxOyBpIDwgbDsgaSArPSBzdGVwICkge1xuXG5cdFx0XHRcdFx0XHR2U3RhcnQuZnJvbUFycmF5KCBwb3NpdGlvbnMsIDMgKiBpICk7XG5cdFx0XHRcdFx0XHR2RW5kLmZyb21BcnJheSggcG9zaXRpb25zLCAzICogaSArIDMgKTtcblxuXHRcdFx0XHRcdFx0dmFyIGRpc3RTcSA9IHJheS5kaXN0YW5jZVNxVG9TZWdtZW50KCB2U3RhcnQsIHZFbmQsIGludGVyUmF5LCBpbnRlclNlZ21lbnQgKTtcblxuXHRcdFx0XHRcdFx0aWYgKCBkaXN0U3EgPiBwcmVjaXNpb25TcSApIGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0XHRpbnRlclJheS5hcHBseU1hdHJpeDQoIHRoaXMubWF0cml4V29ybGQgKTsgLy9Nb3ZlIGJhY2sgdG8gd29ybGQgc3BhY2UgZm9yIGRpc3RhbmNlIGNhbGN1bGF0aW9uXG5cblx0XHRcdFx0XHRcdHZhciBkaXN0YW5jZSA9IHJheWNhc3Rlci5yYXkub3JpZ2luLmRpc3RhbmNlVG8oIGludGVyUmF5ICk7XG5cblx0XHRcdFx0XHRcdGlmICggZGlzdGFuY2UgPCByYXljYXN0ZXIubmVhciB8fCBkaXN0YW5jZSA+IHJheWNhc3Rlci5mYXIgKSBjb250aW51ZTtcblxuXHRcdFx0XHRcdFx0aW50ZXJzZWN0cy5wdXNoKCB7XG5cblx0XHRcdFx0XHRcdFx0ZGlzdGFuY2U6IGRpc3RhbmNlLFxuXHRcdFx0XHRcdFx0XHQvLyBXaGF0IGRvIHdlIHdhbnQ/IGludGVyc2VjdGlvbiBwb2ludCBvbiB0aGUgcmF5IG9yIG9uIHRoZSBzZWdtZW50Pz9cblx0XHRcdFx0XHRcdFx0Ly8gcG9pbnQ6IHJheWNhc3Rlci5yYXkuYXQoIGRpc3RhbmNlICksXG5cdFx0XHRcdFx0XHRcdHBvaW50OiBpbnRlclNlZ21lbnQuY2xvbmUoKS5hcHBseU1hdHJpeDQoIHRoaXMubWF0cml4V29ybGQgKSxcblx0XHRcdFx0XHRcdFx0aW5kZXg6IGksXG5cdFx0XHRcdFx0XHRcdGZhY2U6IG51bGwsXG5cdFx0XHRcdFx0XHRcdGZhY2VJbmRleDogbnVsbCxcblx0XHRcdFx0XHRcdFx0b2JqZWN0OiB0aGlzXG5cblx0XHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAoIGdlb21ldHJ5LmlzR2VvbWV0cnkgKSB7XG5cblx0XHRcdFx0dmFyIHZlcnRpY2VzID0gZ2VvbWV0cnkudmVydGljZXM7XG5cdFx0XHRcdHZhciBuYlZlcnRpY2VzID0gdmVydGljZXMubGVuZ3RoO1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IG5iVmVydGljZXMgLSAxOyBpICs9IHN0ZXAgKSB7XG5cblx0XHRcdFx0XHR2YXIgZGlzdFNxID0gcmF5LmRpc3RhbmNlU3FUb1NlZ21lbnQoIHZlcnRpY2VzWyBpIF0sIHZlcnRpY2VzWyBpICsgMSBdLCBpbnRlclJheSwgaW50ZXJTZWdtZW50ICk7XG5cblx0XHRcdFx0XHRpZiAoIGRpc3RTcSA+IHByZWNpc2lvblNxICkgY29udGludWU7XG5cblx0XHRcdFx0XHRpbnRlclJheS5hcHBseU1hdHJpeDQoIHRoaXMubWF0cml4V29ybGQgKTsgLy9Nb3ZlIGJhY2sgdG8gd29ybGQgc3BhY2UgZm9yIGRpc3RhbmNlIGNhbGN1bGF0aW9uXG5cblx0XHRcdFx0XHR2YXIgZGlzdGFuY2UgPSByYXljYXN0ZXIucmF5Lm9yaWdpbi5kaXN0YW5jZVRvKCBpbnRlclJheSApO1xuXG5cdFx0XHRcdFx0aWYgKCBkaXN0YW5jZSA8IHJheWNhc3Rlci5uZWFyIHx8IGRpc3RhbmNlID4gcmF5Y2FzdGVyLmZhciApIGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0aW50ZXJzZWN0cy5wdXNoKCB7XG5cblx0XHRcdFx0XHRcdGRpc3RhbmNlOiBkaXN0YW5jZSxcblx0XHRcdFx0XHRcdC8vIFdoYXQgZG8gd2Ugd2FudD8gaW50ZXJzZWN0aW9uIHBvaW50IG9uIHRoZSByYXkgb3Igb24gdGhlIHNlZ21lbnQ/P1xuXHRcdFx0XHRcdFx0Ly8gcG9pbnQ6IHJheWNhc3Rlci5yYXkuYXQoIGRpc3RhbmNlICksXG5cdFx0XHRcdFx0XHRwb2ludDogaW50ZXJTZWdtZW50LmNsb25lKCkuYXBwbHlNYXRyaXg0KCB0aGlzLm1hdHJpeFdvcmxkICksXG5cdFx0XHRcdFx0XHRpbmRleDogaSxcblx0XHRcdFx0XHRcdGZhY2U6IG51bGwsXG5cdFx0XHRcdFx0XHRmYWNlSW5kZXg6IG51bGwsXG5cdFx0XHRcdFx0XHRvYmplY3Q6IHRoaXNcblxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fSgpICksXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvciggdGhpcy5nZW9tZXRyeSwgdGhpcy5tYXRlcmlhbCApLmNvcHkoIHRoaXMgKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIExpbmVTZWdtZW50cyggZ2VvbWV0cnksIG1hdGVyaWFsICkge1xuXG5cdExpbmUuY2FsbCggdGhpcywgZ2VvbWV0cnksIG1hdGVyaWFsICk7XG5cblx0dGhpcy50eXBlID0gJ0xpbmVTZWdtZW50cyc7XG5cbn1cblxuTGluZVNlZ21lbnRzLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIExpbmUucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTGluZVNlZ21lbnRzLFxuXG5cdGlzTGluZVNlZ21lbnRzOiB0cnVlXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1ncmV0ZXIgLyBodHRwOi8vZ2l0aHViLmNvbS9tZ3JldGVyXG4gKi9cblxuZnVuY3Rpb24gTGluZUxvb3AoIGdlb21ldHJ5LCBtYXRlcmlhbCApIHtcblxuXHRMaW5lLmNhbGwoIHRoaXMsIGdlb21ldHJ5LCBtYXRlcmlhbCApO1xuXG5cdHRoaXMudHlwZSA9ICdMaW5lTG9vcCc7XG5cbn1cblxuTGluZUxvb3AucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggTGluZS5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBMaW5lTG9vcCxcblxuXHRpc0xpbmVMb29wOiB0cnVlLFxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBjb2xvcjogPGhleD4sXG4gKiAgb3BhY2l0eTogPGZsb2F0PixcbiAqICBtYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIHNpemU6IDxmbG9hdD4sXG4gKiAgc2l6ZUF0dGVudWF0aW9uOiA8Ym9vbD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBQb2ludHNNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1BvaW50c01hdGVyaWFsJztcblxuXHR0aGlzLmNvbG9yID0gbmV3IENvbG9yKCAweGZmZmZmZiApO1xuXG5cdHRoaXMubWFwID0gbnVsbDtcblxuXHR0aGlzLnNpemUgPSAxO1xuXHR0aGlzLnNpemVBdHRlbnVhdGlvbiA9IHRydWU7XG5cblx0dGhpcy5saWdodHMgPSBmYWxzZTtcblxuXHR0aGlzLnNldFZhbHVlcyggcGFyYW1ldGVycyApO1xuXG59XG5cblBvaW50c01hdGVyaWFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE1hdGVyaWFsLnByb3RvdHlwZSApO1xuUG9pbnRzTWF0ZXJpYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUG9pbnRzTWF0ZXJpYWw7XG5cblBvaW50c01hdGVyaWFsLnByb3RvdHlwZS5pc1BvaW50c01hdGVyaWFsID0gdHJ1ZTtcblxuUG9pbnRzTWF0ZXJpYWwucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRNYXRlcmlhbC5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHR0aGlzLmNvbG9yLmNvcHkoIHNvdXJjZS5jb2xvciApO1xuXG5cdHRoaXMubWFwID0gc291cmNlLm1hcDtcblxuXHR0aGlzLnNpemUgPSBzb3VyY2Uuc2l6ZTtcblx0dGhpcy5zaXplQXR0ZW51YXRpb24gPSBzb3VyY2Uuc2l6ZUF0dGVudWF0aW9uO1xuXG5cdHJldHVybiB0aGlzO1xuXG59O1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gUG9pbnRzKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdQb2ludHMnO1xuXG5cdHRoaXMuZ2VvbWV0cnkgPSBnZW9tZXRyeSAhPT0gdW5kZWZpbmVkID8gZ2VvbWV0cnkgOiBuZXcgQnVmZmVyR2VvbWV0cnkoKTtcblx0dGhpcy5tYXRlcmlhbCA9IG1hdGVyaWFsICE9PSB1bmRlZmluZWQgPyBtYXRlcmlhbCA6IG5ldyBQb2ludHNNYXRlcmlhbCggeyBjb2xvcjogTWF0aC5yYW5kb20oKSAqIDB4ZmZmZmZmIH0gKTtcblxufVxuXG5Qb2ludHMucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogUG9pbnRzLFxuXG5cdGlzUG9pbnRzOiB0cnVlLFxuXG5cdHJheWNhc3Q6ICggZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGludmVyc2VNYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXHRcdHZhciByYXkgPSBuZXcgUmF5KCk7XG5cdFx0dmFyIHNwaGVyZSA9IG5ldyBTcGhlcmUoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiByYXljYXN0KCByYXljYXN0ZXIsIGludGVyc2VjdHMgKSB7XG5cblx0XHRcdHZhciBvYmplY3QgPSB0aGlzO1xuXHRcdFx0dmFyIGdlb21ldHJ5ID0gdGhpcy5nZW9tZXRyeTtcblx0XHRcdHZhciBtYXRyaXhXb3JsZCA9IHRoaXMubWF0cml4V29ybGQ7XG5cdFx0XHR2YXIgdGhyZXNob2xkID0gcmF5Y2FzdGVyLnBhcmFtcy5Qb2ludHMudGhyZXNob2xkO1xuXG5cdFx0XHQvLyBDaGVja2luZyBib3VuZGluZ1NwaGVyZSBkaXN0YW5jZSB0byByYXlcblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSA9PT0gbnVsbCApIGdlb21ldHJ5LmNvbXB1dGVCb3VuZGluZ1NwaGVyZSgpO1xuXG5cdFx0XHRzcGhlcmUuY29weSggZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUgKTtcblx0XHRcdHNwaGVyZS5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cdFx0XHRzcGhlcmUucmFkaXVzICs9IHRocmVzaG9sZDtcblxuXHRcdFx0aWYgKCByYXljYXN0ZXIucmF5LmludGVyc2VjdHNTcGhlcmUoIHNwaGVyZSApID09PSBmYWxzZSApIHJldHVybjtcblxuXHRcdFx0Ly9cblxuXHRcdFx0aW52ZXJzZU1hdHJpeC5nZXRJbnZlcnNlKCBtYXRyaXhXb3JsZCApO1xuXHRcdFx0cmF5LmNvcHkoIHJheWNhc3Rlci5yYXkgKS5hcHBseU1hdHJpeDQoIGludmVyc2VNYXRyaXggKTtcblxuXHRcdFx0dmFyIGxvY2FsVGhyZXNob2xkID0gdGhyZXNob2xkIC8gKCAoIHRoaXMuc2NhbGUueCArIHRoaXMuc2NhbGUueSArIHRoaXMuc2NhbGUueiApIC8gMyApO1xuXHRcdFx0dmFyIGxvY2FsVGhyZXNob2xkU3EgPSBsb2NhbFRocmVzaG9sZCAqIGxvY2FsVGhyZXNob2xkO1xuXHRcdFx0dmFyIHBvc2l0aW9uID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0ZnVuY3Rpb24gdGVzdFBvaW50KCBwb2ludCwgaW5kZXggKSB7XG5cblx0XHRcdFx0dmFyIHJheVBvaW50RGlzdGFuY2VTcSA9IHJheS5kaXN0YW5jZVNxVG9Qb2ludCggcG9pbnQgKTtcblxuXHRcdFx0XHRpZiAoIHJheVBvaW50RGlzdGFuY2VTcSA8IGxvY2FsVGhyZXNob2xkU3EgKSB7XG5cblx0XHRcdFx0XHR2YXIgaW50ZXJzZWN0UG9pbnQgPSByYXkuY2xvc2VzdFBvaW50VG9Qb2ludCggcG9pbnQgKTtcblx0XHRcdFx0XHRpbnRlcnNlY3RQb2ludC5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0XHR2YXIgZGlzdGFuY2UgPSByYXljYXN0ZXIucmF5Lm9yaWdpbi5kaXN0YW5jZVRvKCBpbnRlcnNlY3RQb2ludCApO1xuXG5cdFx0XHRcdFx0aWYgKCBkaXN0YW5jZSA8IHJheWNhc3Rlci5uZWFyIHx8IGRpc3RhbmNlID4gcmF5Y2FzdGVyLmZhciApIHJldHVybjtcblxuXHRcdFx0XHRcdGludGVyc2VjdHMucHVzaCgge1xuXG5cdFx0XHRcdFx0XHRkaXN0YW5jZTogZGlzdGFuY2UsXG5cdFx0XHRcdFx0XHRkaXN0YW5jZVRvUmF5OiBNYXRoLnNxcnQoIHJheVBvaW50RGlzdGFuY2VTcSApLFxuXHRcdFx0XHRcdFx0cG9pbnQ6IGludGVyc2VjdFBvaW50LmNsb25lKCksXG5cdFx0XHRcdFx0XHRpbmRleDogaW5kZXgsXG5cdFx0XHRcdFx0XHRmYWNlOiBudWxsLFxuXHRcdFx0XHRcdFx0b2JqZWN0OiBvYmplY3RcblxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBnZW9tZXRyeS5pc0J1ZmZlckdlb21ldHJ5ICkge1xuXG5cdFx0XHRcdHZhciBpbmRleCA9IGdlb21ldHJ5LmluZGV4O1xuXHRcdFx0XHR2YXIgYXR0cmlidXRlcyA9IGdlb21ldHJ5LmF0dHJpYnV0ZXM7XG5cdFx0XHRcdHZhciBwb3NpdGlvbnMgPSBhdHRyaWJ1dGVzLnBvc2l0aW9uLmFycmF5O1xuXG5cdFx0XHRcdGlmICggaW5kZXggIT09IG51bGwgKSB7XG5cblx0XHRcdFx0XHR2YXIgaW5kaWNlcyA9IGluZGV4LmFycmF5O1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IGluZGljZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdHZhciBhID0gaW5kaWNlc1sgaSBdO1xuXG5cdFx0XHRcdFx0XHRwb3NpdGlvbi5mcm9tQXJyYXkoIHBvc2l0aW9ucywgYSAqIDMgKTtcblxuXHRcdFx0XHRcdFx0dGVzdFBvaW50KCBwb3NpdGlvbiwgYSApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBwb3NpdGlvbnMubGVuZ3RoIC8gMzsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdHBvc2l0aW9uLmZyb21BcnJheSggcG9zaXRpb25zLCBpICogMyApO1xuXG5cdFx0XHRcdFx0XHR0ZXN0UG9pbnQoIHBvc2l0aW9uLCBpICk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHZhciB2ZXJ0aWNlcyA9IGdlb21ldHJ5LnZlcnRpY2VzO1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IHZlcnRpY2VzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHR0ZXN0UG9pbnQoIHZlcnRpY2VzWyBpIF0sIGkgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0fSgpICksXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvciggdGhpcy5nZW9tZXRyeSwgdGhpcy5tYXRlcmlhbCApLmNvcHkoIHRoaXMgKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEdyb3VwKCkge1xuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnR3JvdXAnO1xuXG59XG5cbkdyb3VwLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IEdyb3VwXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFZpZGVvVGV4dHVyZSggdmlkZW8sIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSApIHtcblxuXHRUZXh0dXJlLmNhbGwoIHRoaXMsIHZpZGVvLCBtYXBwaW5nLCB3cmFwUywgd3JhcFQsIG1hZ0ZpbHRlciwgbWluRmlsdGVyLCBmb3JtYXQsIHR5cGUsIGFuaXNvdHJvcHkgKTtcblxuXHR0aGlzLmdlbmVyYXRlTWlwbWFwcyA9IGZhbHNlO1xuXG5cdHZhciBzY29wZSA9IHRoaXM7XG5cblx0ZnVuY3Rpb24gdXBkYXRlKCkge1xuXG5cdFx0cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCB1cGRhdGUgKTtcblxuXHRcdGlmICggdmlkZW8ucmVhZHlTdGF0ZSA+PSB2aWRlby5IQVZFX0NVUlJFTlRfREFUQSApIHtcblxuXHRcdFx0c2NvcGUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0fVxuXG5cdH1cblxuXHR1cGRhdGUoKTtcblxufVxuXG5WaWRlb1RleHR1cmUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggVGV4dHVyZS5wcm90b3R5cGUgKTtcblZpZGVvVGV4dHVyZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBWaWRlb1RleHR1cmU7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBDb21wcmVzc2VkVGV4dHVyZSggbWlwbWFwcywgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCB0eXBlLCBtYXBwaW5nLCB3cmFwUywgd3JhcFQsIG1hZ0ZpbHRlciwgbWluRmlsdGVyLCBhbmlzb3Ryb3B5LCBlbmNvZGluZyApIHtcblxuXHRUZXh0dXJlLmNhbGwoIHRoaXMsIG51bGwsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSwgZW5jb2RpbmcgKTtcblxuXHR0aGlzLmltYWdlID0geyB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0IH07XG5cdHRoaXMubWlwbWFwcyA9IG1pcG1hcHM7XG5cblx0Ly8gbm8gZmxpcHBpbmcgZm9yIGN1YmUgdGV4dHVyZXNcblx0Ly8gKGFsc28gZmxpcHBpbmcgZG9lc24ndCB3b3JrIGZvciBjb21wcmVzc2VkIHRleHR1cmVzIClcblxuXHR0aGlzLmZsaXBZID0gZmFsc2U7XG5cblx0Ly8gY2FuJ3QgZ2VuZXJhdGUgbWlwbWFwcyBmb3IgY29tcHJlc3NlZCB0ZXh0dXJlc1xuXHQvLyBtaXBzIG11c3QgYmUgZW1iZWRkZWQgaW4gRERTIGZpbGVzXG5cblx0dGhpcy5nZW5lcmF0ZU1pcG1hcHMgPSBmYWxzZTtcblxufVxuXG5Db21wcmVzc2VkVGV4dHVyZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBUZXh0dXJlLnByb3RvdHlwZSApO1xuQ29tcHJlc3NlZFRleHR1cmUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ29tcHJlc3NlZFRleHR1cmU7XG5cbkNvbXByZXNzZWRUZXh0dXJlLnByb3RvdHlwZS5pc0NvbXByZXNzZWRUZXh0dXJlID0gdHJ1ZTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIENhbnZhc1RleHR1cmUoIGNhbnZhcywgbWFwcGluZywgd3JhcFMsIHdyYXBULCBtYWdGaWx0ZXIsIG1pbkZpbHRlciwgZm9ybWF0LCB0eXBlLCBhbmlzb3Ryb3B5ICkge1xuXG5cdFRleHR1cmUuY2FsbCggdGhpcywgY2FudmFzLCBtYXBwaW5nLCB3cmFwUywgd3JhcFQsIG1hZ0ZpbHRlciwgbWluRmlsdGVyLCBmb3JtYXQsIHR5cGUsIGFuaXNvdHJvcHkgKTtcblxuXHR0aGlzLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxufVxuXG5DYW52YXNUZXh0dXJlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIFRleHR1cmUucHJvdG90eXBlICk7XG5DYW52YXNUZXh0dXJlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IENhbnZhc1RleHR1cmU7XG5cbi8qKlxuICogQGF1dGhvciBNYXR0IERlc0xhdXJpZXJzIC8gQG1hdHRkZXNsXG4gKiBAYXV0aG9yIGF0aXggLyBhcnRodXJzaWxiZXIuZGVcbiAqL1xuXG5mdW5jdGlvbiBEZXB0aFRleHR1cmUoIHdpZHRoLCBoZWlnaHQsIHR5cGUsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGFuaXNvdHJvcHksIGZvcm1hdCApIHtcblxuXHRmb3JtYXQgPSBmb3JtYXQgIT09IHVuZGVmaW5lZCA/IGZvcm1hdCA6IERlcHRoRm9ybWF0O1xuXG5cdGlmICggZm9ybWF0ICE9PSBEZXB0aEZvcm1hdCAmJiBmb3JtYXQgIT09IERlcHRoU3RlbmNpbEZvcm1hdCApIHtcblxuXHRcdHRocm93IG5ldyBFcnJvciggJ0RlcHRoVGV4dHVyZSBmb3JtYXQgbXVzdCBiZSBlaXRoZXIgVEhSRUUuRGVwdGhGb3JtYXQgb3IgVEhSRUUuRGVwdGhTdGVuY2lsRm9ybWF0JyApXG5cblx0fVxuXG5cdGlmICggdHlwZSA9PT0gdW5kZWZpbmVkICYmIGZvcm1hdCA9PT0gRGVwdGhGb3JtYXQgKSB0eXBlID0gVW5zaWduZWRTaG9ydFR5cGU7XG5cdGlmICggdHlwZSA9PT0gdW5kZWZpbmVkICYmIGZvcm1hdCA9PT0gRGVwdGhTdGVuY2lsRm9ybWF0ICkgdHlwZSA9IFVuc2lnbmVkSW50MjQ4VHlwZTtcblxuXHRUZXh0dXJlLmNhbGwoIHRoaXMsIG51bGwsIG1hcHBpbmcsIHdyYXBTLCB3cmFwVCwgbWFnRmlsdGVyLCBtaW5GaWx0ZXIsIGZvcm1hdCwgdHlwZSwgYW5pc290cm9weSApO1xuXG5cdHRoaXMuaW1hZ2UgPSB7IHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfTtcblxuXHR0aGlzLm1hZ0ZpbHRlciA9IG1hZ0ZpbHRlciAhPT0gdW5kZWZpbmVkID8gbWFnRmlsdGVyIDogTmVhcmVzdEZpbHRlcjtcblx0dGhpcy5taW5GaWx0ZXIgPSBtaW5GaWx0ZXIgIT09IHVuZGVmaW5lZCA/IG1pbkZpbHRlciA6IE5lYXJlc3RGaWx0ZXI7XG5cblx0dGhpcy5mbGlwWSA9IGZhbHNlO1xuXHR0aGlzLmdlbmVyYXRlTWlwbWFwc1x0PSBmYWxzZTtcblxufVxuXG5EZXB0aFRleHR1cmUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggVGV4dHVyZS5wcm90b3R5cGUgKTtcbkRlcHRoVGV4dHVyZS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBEZXB0aFRleHR1cmU7XG5EZXB0aFRleHR1cmUucHJvdG90eXBlLmlzRGVwdGhUZXh0dXJlID0gdHJ1ZTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG5mdW5jdGlvbiBXaXJlZnJhbWVHZW9tZXRyeSggZ2VvbWV0cnkgKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdXaXJlZnJhbWVHZW9tZXRyeSc7XG5cblx0Ly8gYnVmZmVyXG5cblx0dmFyIHZlcnRpY2VzID0gW107XG5cblx0Ly8gaGVscGVyIHZhcmlhYmxlc1xuXG5cdHZhciBpLCBqLCBsLCBvLCBvbDtcblx0dmFyIGVkZ2UgPSBbIDAsIDAgXSwgZWRnZXMgPSB7fSwgZSwgZWRnZTEsIGVkZ2UyO1xuXHR2YXIga2V5LCBrZXlzID0gWyAnYScsICdiJywgJ2MnIF07XG5cdHZhciB2ZXJ0ZXg7XG5cblx0Ly8gZGlmZmVyZW50IGxvZ2ljIGZvciBHZW9tZXRyeSBhbmQgQnVmZmVyR2VvbWV0cnlcblxuXHRpZiAoIGdlb21ldHJ5ICYmIGdlb21ldHJ5LmlzR2VvbWV0cnkgKSB7XG5cblx0XHQvLyBjcmVhdGUgYSBkYXRhIHN0cnVjdHVyZSB0aGF0IGNvbnRhaW5zIGFsbCBlZGdlcyB3aXRob3V0IGR1cGxpY2F0ZXNcblxuXHRcdHZhciBmYWNlcyA9IGdlb21ldHJ5LmZhY2VzO1xuXG5cdFx0Zm9yICggaSA9IDAsIGwgPSBmYWNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgZmFjZSA9IGZhY2VzWyBpIF07XG5cblx0XHRcdGZvciAoIGogPSAwOyBqIDwgMzsgaiArKyApIHtcblxuXHRcdFx0XHRlZGdlMSA9IGZhY2VbIGtleXNbIGogXSBdO1xuXHRcdFx0XHRlZGdlMiA9IGZhY2VbIGtleXNbICggaiArIDEgKSAlIDMgXSBdO1xuXHRcdFx0XHRlZGdlWyAwIF0gPSBNYXRoLm1pbiggZWRnZTEsIGVkZ2UyICk7IC8vIHNvcnRpbmcgcHJldmVudHMgZHVwbGljYXRlc1xuXHRcdFx0XHRlZGdlWyAxIF0gPSBNYXRoLm1heCggZWRnZTEsIGVkZ2UyICk7XG5cblx0XHRcdFx0a2V5ID0gZWRnZVsgMCBdICsgJywnICsgZWRnZVsgMSBdO1xuXG5cdFx0XHRcdGlmICggZWRnZXNbIGtleSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRlZGdlc1sga2V5IF0gPSB7IGluZGV4MTogZWRnZVsgMCBdLCBpbmRleDI6IGVkZ2VbIDEgXSB9O1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gZ2VuZXJhdGUgdmVydGljZXNcblxuXHRcdGZvciAoIGtleSBpbiBlZGdlcyApIHtcblxuXHRcdFx0ZSA9IGVkZ2VzWyBrZXkgXTtcblxuXHRcdFx0dmVydGV4ID0gZ2VvbWV0cnkudmVydGljZXNbIGUuaW5kZXgxIF07XG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56ICk7XG5cblx0XHRcdHZlcnRleCA9IGdlb21ldHJ5LnZlcnRpY2VzWyBlLmluZGV4MiBdO1xuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0fVxuXG5cdH0gZWxzZSBpZiAoIGdlb21ldHJ5ICYmIGdlb21ldHJ5LmlzQnVmZmVyR2VvbWV0cnkgKSB7XG5cblx0XHR2YXIgcG9zaXRpb24sIGluZGljZXMsIGdyb3Vwcztcblx0XHR2YXIgZ3JvdXAsIHN0YXJ0LCBjb3VudDtcblx0XHR2YXIgaW5kZXgxLCBpbmRleDI7XG5cblx0XHR2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0aWYgKCBnZW9tZXRyeS5pbmRleCAhPT0gbnVsbCApIHtcblxuXHRcdFx0Ly8gaW5kZXhlZCBCdWZmZXJHZW9tZXRyeVxuXG5cdFx0XHRwb3NpdGlvbiA9IGdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cdFx0XHRpbmRpY2VzID0gZ2VvbWV0cnkuaW5kZXg7XG5cdFx0XHRncm91cHMgPSBnZW9tZXRyeS5ncm91cHM7XG5cblx0XHRcdGlmICggZ3JvdXBzLmxlbmd0aCA9PT0gMCApIHtcblxuXHRcdFx0XHRncm91cHMgPSBbIHsgc3RhcnQ6IDAsIGNvdW50OiBpbmRpY2VzLmNvdW50LCBtYXRlcmlhbEluZGV4OiAwIH0gXTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBjcmVhdGUgYSBkYXRhIHN0cnVjdHVyZSB0aGF0IGNvbnRhaW5zIGFsbCBlZ2VzIHdpdGhvdXQgZHVwbGljYXRlc1xuXG5cdFx0XHRmb3IgKCBvID0gMCwgb2wgPSBncm91cHMubGVuZ3RoOyBvIDwgb2w7ICsrIG8gKSB7XG5cblx0XHRcdFx0Z3JvdXAgPSBncm91cHNbIG8gXTtcblxuXHRcdFx0XHRzdGFydCA9IGdyb3VwLnN0YXJ0O1xuXHRcdFx0XHRjb3VudCA9IGdyb3VwLmNvdW50O1xuXG5cdFx0XHRcdGZvciAoIGkgPSBzdGFydCwgbCA9ICggc3RhcnQgKyBjb3VudCApOyBpIDwgbDsgaSArPSAzICkge1xuXG5cdFx0XHRcdFx0Zm9yICggaiA9IDA7IGogPCAzOyBqICsrICkge1xuXG5cdFx0XHRcdFx0XHRlZGdlMSA9IGluZGljZXMuZ2V0WCggaSArIGogKTtcblx0XHRcdFx0XHRcdGVkZ2UyID0gaW5kaWNlcy5nZXRYKCBpICsgKCBqICsgMSApICUgMyApO1xuXHRcdFx0XHRcdFx0ZWRnZVsgMCBdID0gTWF0aC5taW4oIGVkZ2UxLCBlZGdlMiApOyAvLyBzb3J0aW5nIHByZXZlbnRzIGR1cGxpY2F0ZXNcblx0XHRcdFx0XHRcdGVkZ2VbIDEgXSA9IE1hdGgubWF4KCBlZGdlMSwgZWRnZTIgKTtcblxuXHRcdFx0XHRcdFx0a2V5ID0gZWRnZVsgMCBdICsgJywnICsgZWRnZVsgMSBdO1xuXG5cdFx0XHRcdFx0XHRpZiAoIGVkZ2VzWyBrZXkgXSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0XHRcdGVkZ2VzWyBrZXkgXSA9IHsgaW5kZXgxOiBlZGdlWyAwIF0sIGluZGV4MjogZWRnZVsgMSBdIH07XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gZ2VuZXJhdGUgdmVydGljZXNcblxuXHRcdFx0Zm9yICgga2V5IGluIGVkZ2VzICkge1xuXG5cdFx0XHRcdGUgPSBlZGdlc1sga2V5IF07XG5cblx0XHRcdFx0dmVydGV4LmZyb21CdWZmZXJBdHRyaWJ1dGUoIHBvc2l0aW9uLCBlLmluZGV4MSApO1xuXHRcdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56ICk7XG5cblx0XHRcdFx0dmVydGV4LmZyb21CdWZmZXJBdHRyaWJ1dGUoIHBvc2l0aW9uLCBlLmluZGV4MiApO1xuXHRcdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56ICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIG5vbi1pbmRleGVkIEJ1ZmZlckdlb21ldHJ5XG5cblx0XHRcdHBvc2l0aW9uID0gZ2VvbWV0cnkuYXR0cmlidXRlcy5wb3NpdGlvbjtcblxuXHRcdFx0Zm9yICggaSA9IDAsIGwgPSAoIHBvc2l0aW9uLmNvdW50IC8gMyApOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRmb3IgKCBqID0gMDsgaiA8IDM7IGogKysgKSB7XG5cblx0XHRcdFx0XHQvLyB0aHJlZSBlZGdlcyBwZXIgdHJpYW5nbGUsIGFuIGVkZ2UgaXMgcmVwcmVzZW50ZWQgYXMgKGluZGV4MSwgaW5kZXgyKVxuXHRcdFx0XHRcdC8vIGUuZy4gdGhlIGZpcnN0IHRyaWFuZ2xlIGhhcyB0aGUgZm9sbG93aW5nIGVkZ2VzOiAoMCwxKSwoMSwyKSwoMiwwKVxuXG5cdFx0XHRcdFx0aW5kZXgxID0gMyAqIGkgKyBqO1xuXHRcdFx0XHRcdHZlcnRleC5mcm9tQnVmZmVyQXR0cmlidXRlKCBwb3NpdGlvbiwgaW5kZXgxICk7XG5cdFx0XHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0XHRcdFx0aW5kZXgyID0gMyAqIGkgKyAoICggaiArIDEgKSAlIDMgKTtcblx0XHRcdFx0XHR2ZXJ0ZXguZnJvbUJ1ZmZlckF0dHJpYnV0ZSggcG9zaXRpb24sIGluZGV4MiApO1xuXHRcdFx0XHRcdHZlcnRpY2VzLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gYnVpbGQgZ2VvbWV0cnlcblxuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblxufVxuXG5XaXJlZnJhbWVHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcbldpcmVmcmFtZUdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFdpcmVmcmFtZUdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3Igeno4NSAvIGh0dHBzOi8vZ2l0aHViLmNvbS96ejg1XG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICpcbiAqIFBhcmFtZXRyaWMgU3VyZmFjZXMgR2VvbWV0cnlcbiAqIGJhc2VkIG9uIHRoZSBicmlsbGlhbnQgYXJ0aWNsZSBieSBAcHJpZGVvdXQgaHR0cDovL3ByaWRlb3V0Lm5ldC9ibG9nLz9wPTQ0XG4gKi9cblxuLy8gUGFyYW1ldHJpY0dlb21ldHJ5XG5cbmZ1bmN0aW9uIFBhcmFtZXRyaWNHZW9tZXRyeSggZnVuYywgc2xpY2VzLCBzdGFja3MgKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdQYXJhbWV0cmljR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRmdW5jOiBmdW5jLFxuXHRcdHNsaWNlczogc2xpY2VzLFxuXHRcdHN0YWNrczogc3RhY2tzXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBQYXJhbWV0cmljQnVmZmVyR2VvbWV0cnkoIGZ1bmMsIHNsaWNlcywgc3RhY2tzICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuUGFyYW1ldHJpY0dlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuUGFyYW1ldHJpY0dlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBhcmFtZXRyaWNHZW9tZXRyeTtcblxuLy8gUGFyYW1ldHJpY0J1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIFBhcmFtZXRyaWNCdWZmZXJHZW9tZXRyeSggZnVuYywgc2xpY2VzLCBzdGFja3MgKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdQYXJhbWV0cmljQnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRmdW5jOiBmdW5jLFxuXHRcdHNsaWNlczogc2xpY2VzLFxuXHRcdHN0YWNrczogc3RhY2tzXG5cdH07XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0dmFyIEVQUyA9IDAuMDAwMDE7XG5cblx0dmFyIG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0dmFyIHAwID0gbmV3IFZlY3RvcjMoKSwgcDEgPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgcHUgPSBuZXcgVmVjdG9yMygpLCBwdiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0dmFyIGksIGo7XG5cblx0Ly8gZ2VuZXJhdGUgdmVydGljZXMsIG5vcm1hbHMgYW5kIHV2c1xuXG5cdHZhciBzbGljZUNvdW50ID0gc2xpY2VzICsgMTtcblxuXHRmb3IgKCBpID0gMDsgaSA8PSBzdGFja3M7IGkgKysgKSB7XG5cblx0XHR2YXIgdiA9IGkgLyBzdGFja3M7XG5cblx0XHRmb3IgKCBqID0gMDsgaiA8PSBzbGljZXM7IGogKysgKSB7XG5cblx0XHRcdHZhciB1ID0gaiAvIHNsaWNlcztcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHAwID0gZnVuYyggdSwgdiwgcDAgKTtcblx0XHRcdHZlcnRpY2VzLnB1c2goIHAwLngsIHAwLnksIHAwLnogKTtcblxuXHRcdFx0Ly8gbm9ybWFsXG5cblx0XHRcdC8vIGFwcHJveGltYXRlIHRhbmdlbnQgdmVjdG9ycyB2aWEgZmluaXRlIGRpZmZlcmVuY2VzXG5cblx0XHRcdGlmICggdSAtIEVQUyA+PSAwICkge1xuXG5cdFx0XHRcdHAxID0gZnVuYyggdSAtIEVQUywgdiwgcDEgKTtcblx0XHRcdFx0cHUuc3ViVmVjdG9ycyggcDAsIHAxICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0cDEgPSBmdW5jKCB1ICsgRVBTLCB2LCBwMSApO1xuXHRcdFx0XHRwdS5zdWJWZWN0b3JzKCBwMSwgcDAgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHYgLSBFUFMgPj0gMCApIHtcblxuXHRcdFx0XHRwMSA9IGZ1bmMoIHUsIHYgLSBFUFMsIHAxICk7XG5cdFx0XHRcdHB2LnN1YlZlY3RvcnMoIHAwLCBwMSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHAxID0gZnVuYyggdSwgdiArIEVQUywgcDEgKTtcblx0XHRcdFx0cHYuc3ViVmVjdG9ycyggcDEsIHAwICk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gY3Jvc3MgcHJvZHVjdCBvZiB0YW5nZW50IHZlY3RvcnMgcmV0dXJucyBzdXJmYWNlIG5vcm1hbFxuXG5cdFx0XHRub3JtYWwuY3Jvc3NWZWN0b3JzKCBwdSwgcHYgKS5ub3JtYWxpemUoKTtcblx0XHRcdG5vcm1hbHMucHVzaCggbm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1dnMucHVzaCggdSwgdiApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBnZW5lcmF0ZSBpbmRpY2VzXG5cblx0Zm9yICggaSA9IDA7IGkgPCBzdGFja3M7IGkgKysgKSB7XG5cblx0XHRmb3IgKCBqID0gMDsgaiA8IHNsaWNlczsgaiArKyApIHtcblxuXHRcdFx0dmFyIGEgPSBpICogc2xpY2VDb3VudCArIGo7XG5cdFx0XHR2YXIgYiA9IGkgKiBzbGljZUNvdW50ICsgaiArIDE7XG5cdFx0XHR2YXIgYyA9ICggaSArIDEgKSAqIHNsaWNlQ291bnQgKyBqICsgMTtcblx0XHRcdHZhciBkID0gKCBpICsgMSApICogc2xpY2VDb3VudCArIGo7XG5cblx0XHRcdC8vIGZhY2VzIG9uZSBhbmQgdHdvXG5cblx0XHRcdGluZGljZXMucHVzaCggYSwgYiwgZCApO1xuXHRcdFx0aW5kaWNlcy5wdXNoKCBiLCBjLCBkICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIGJ1aWxkIGdlb21ldHJ5XG5cblx0dGhpcy5zZXRJbmRleCggaW5kaWNlcyApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggbm9ybWFscywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkgKTtcblxufVxuXG5QYXJhbWV0cmljQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5QYXJhbWV0cmljQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUGFyYW1ldHJpY0J1ZmZlckdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3IgY2xvY2t3b3JrZ2VlayAvIGh0dHBzOi8vZ2l0aHViLmNvbS9jbG9ja3dvcmtnZWVrXG4gKiBAYXV0aG9yIHRpbW90aHlwcmF0bGV5IC8gaHR0cHM6Ly9naXRodWIuY29tL3RpbW90aHlwcmF0bGV5XG4gKiBAYXV0aG9yIFdlc3RMYW5nbGV5IC8gaHR0cDovL2dpdGh1Yi5jb20vV2VzdExhbmdsZXlcbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gUG9seWhlZHJvbkdlb21ldHJ5XG5cbmZ1bmN0aW9uIFBvbHloZWRyb25HZW9tZXRyeSggdmVydGljZXMsIGluZGljZXMsIHJhZGl1cywgZGV0YWlsICkge1xuXG5cdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnUG9seWhlZHJvbkdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0dmVydGljZXM6IHZlcnRpY2VzLFxuXHRcdGluZGljZXM6IGluZGljZXMsXG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IFBvbHloZWRyb25CdWZmZXJHZW9tZXRyeSggdmVydGljZXMsIGluZGljZXMsIHJhZGl1cywgZGV0YWlsICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuUG9seWhlZHJvbkdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuUG9seWhlZHJvbkdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBvbHloZWRyb25HZW9tZXRyeTtcblxuLy8gUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIFBvbHloZWRyb25CdWZmZXJHZW9tZXRyeSggdmVydGljZXMsIGluZGljZXMsIHJhZGl1cywgZGV0YWlsICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0dmVydGljZXM6IHZlcnRpY2VzLFxuXHRcdGluZGljZXM6IGluZGljZXMsXG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxuXHRyYWRpdXMgPSByYWRpdXMgfHwgMTtcblx0ZGV0YWlsID0gZGV0YWlsIHx8IDA7XG5cblx0Ly8gZGVmYXVsdCBidWZmZXIgZGF0YVxuXG5cdHZhciB2ZXJ0ZXhCdWZmZXIgPSBbXTtcblx0dmFyIHV2QnVmZmVyID0gW107XG5cblx0Ly8gdGhlIHN1YmRpdmlzaW9uIGNyZWF0ZXMgdGhlIHZlcnRleCBidWZmZXIgZGF0YVxuXG5cdHN1YmRpdmlkZSggZGV0YWlsICk7XG5cblx0Ly8gYWxsIHZlcnRpY2VzIHNob3VsZCBsaWUgb24gYSBjb25jZXB0dWFsIHNwaGVyZSB3aXRoIGEgZ2l2ZW4gcmFkaXVzXG5cblx0YXBwcGx5UmFkaXVzKCByYWRpdXMgKTtcblxuXHQvLyBmaW5hbGx5LCBjcmVhdGUgdGhlIHV2IGRhdGFcblxuXHRnZW5lcmF0ZVVWcygpO1xuXG5cdC8vIGJ1aWxkIG5vbi1pbmRleGVkIGdlb21ldHJ5XG5cblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0ZXhCdWZmZXIsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ25vcm1hbCcsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0ZXhCdWZmZXIuc2xpY2UoKSwgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZCdWZmZXIsIDIgKSApO1xuXHR0aGlzLm5vcm1hbGl6ZU5vcm1hbHMoKTtcblxuXHQvLyBoZWxwZXIgZnVuY3Rpb25zXG5cblx0ZnVuY3Rpb24gc3ViZGl2aWRlKCBkZXRhaWwgKSB7XG5cblx0XHR2YXIgYSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIGIgPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBjID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdC8vIGl0ZXJhdGUgb3ZlciBhbGwgZmFjZXMgYW5kIGFwcGx5IGEgc3ViZGl2aXNvbiB3aXRoIHRoZSBnaXZlbiBkZXRhaWwgdmFsdWVcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpICs9IDMgKSB7XG5cblx0XHRcdC8vIGdldCB0aGUgdmVydGljZXMgb2YgdGhlIGZhY2VcblxuXHRcdFx0Z2V0VmVydGV4QnlJbmRleCggaW5kaWNlc1sgaSArIDAgXSwgYSApO1xuXHRcdFx0Z2V0VmVydGV4QnlJbmRleCggaW5kaWNlc1sgaSArIDEgXSwgYiApO1xuXHRcdFx0Z2V0VmVydGV4QnlJbmRleCggaW5kaWNlc1sgaSArIDIgXSwgYyApO1xuXG5cdFx0XHQvLyBwZXJmb3JtIHN1YmRpdmlzaW9uXG5cblx0XHRcdHN1YmRpdmlkZUZhY2UoIGEsIGIsIGMsIGRldGFpbCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBzdWJkaXZpZGVGYWNlKCBhLCBiLCBjLCBkZXRhaWwgKSB7XG5cblx0XHR2YXIgY29scyA9IE1hdGgucG93KCAyLCBkZXRhaWwgKTtcblxuXHRcdC8vIHdlIHVzZSB0aGlzIG11bHRpZGltZW5zaW9uYWwgYXJyYXkgYXMgYSBkYXRhIHN0cnVjdHVyZSBmb3IgY3JlYXRpbmcgdGhlIHN1YmRpdmlzaW9uXG5cblx0XHR2YXIgdiA9IFtdO1xuXG5cdFx0dmFyIGksIGo7XG5cblx0XHQvLyBjb25zdHJ1Y3QgYWxsIG9mIHRoZSB2ZXJ0aWNlcyBmb3IgdGhpcyBzdWJkaXZpc2lvblxuXG5cdFx0Zm9yICggaSA9IDA7IGkgPD0gY29sczsgaSArKyApIHtcblxuXHRcdFx0dlsgaSBdID0gW107XG5cblx0XHRcdHZhciBhaiA9IGEuY2xvbmUoKS5sZXJwKCBjLCBpIC8gY29scyApO1xuXHRcdFx0dmFyIGJqID0gYi5jbG9uZSgpLmxlcnAoIGMsIGkgLyBjb2xzICk7XG5cblx0XHRcdHZhciByb3dzID0gY29scyAtIGk7XG5cblx0XHRcdGZvciAoIGogPSAwOyBqIDw9IHJvd3M7IGogKysgKSB7XG5cblx0XHRcdFx0aWYgKCBqID09PSAwICYmIGkgPT09IGNvbHMgKSB7XG5cblx0XHRcdFx0XHR2WyBpIF1bIGogXSA9IGFqO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHR2WyBpIF1bIGogXSA9IGFqLmNsb25lKCkubGVycCggYmosIGogLyByb3dzICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHQvLyBjb25zdHJ1Y3QgYWxsIG9mIHRoZSBmYWNlc1xuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBjb2xzOyBpICsrICkge1xuXG5cdFx0XHRmb3IgKCBqID0gMDsgaiA8IDIgKiAoIGNvbHMgLSBpICkgLSAxOyBqICsrICkge1xuXG5cdFx0XHRcdHZhciBrID0gTWF0aC5mbG9vciggaiAvIDIgKTtcblxuXHRcdFx0XHRpZiAoIGogJSAyID09PSAwICkge1xuXG5cdFx0XHRcdFx0cHVzaFZlcnRleCggdlsgaSBdWyBrICsgMSBdICk7XG5cdFx0XHRcdFx0cHVzaFZlcnRleCggdlsgaSArIDEgXVsgayBdICk7XG5cdFx0XHRcdFx0cHVzaFZlcnRleCggdlsgaSBdWyBrIF0gKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0cHVzaFZlcnRleCggdlsgaSBdWyBrICsgMSBdICk7XG5cdFx0XHRcdFx0cHVzaFZlcnRleCggdlsgaSArIDEgXVsgayArIDEgXSApO1xuXHRcdFx0XHRcdHB1c2hWZXJ0ZXgoIHZbIGkgKyAxIF1bIGsgXSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBhcHBwbHlSYWRpdXMoIHJhZGl1cyApIHtcblxuXHRcdHZhciB2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0Ly8gaXRlcmF0ZSBvdmVyIHRoZSBlbnRpcmUgYnVmZmVyIGFuZCBhcHBseSB0aGUgcmFkaXVzIHRvIGVhY2ggdmVydGV4XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCB2ZXJ0ZXhCdWZmZXIubGVuZ3RoOyBpICs9IDMgKSB7XG5cblx0XHRcdHZlcnRleC54ID0gdmVydGV4QnVmZmVyWyBpICsgMCBdO1xuXHRcdFx0dmVydGV4LnkgPSB2ZXJ0ZXhCdWZmZXJbIGkgKyAxIF07XG5cdFx0XHR2ZXJ0ZXgueiA9IHZlcnRleEJ1ZmZlclsgaSArIDIgXTtcblxuXHRcdFx0dmVydGV4Lm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKCByYWRpdXMgKTtcblxuXHRcdFx0dmVydGV4QnVmZmVyWyBpICsgMCBdID0gdmVydGV4Lng7XG5cdFx0XHR2ZXJ0ZXhCdWZmZXJbIGkgKyAxIF0gPSB2ZXJ0ZXgueTtcblx0XHRcdHZlcnRleEJ1ZmZlclsgaSArIDIgXSA9IHZlcnRleC56O1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVVWcygpIHtcblxuXHRcdHZhciB2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdmVydGV4QnVmZmVyLmxlbmd0aDsgaSArPSAzICkge1xuXG5cdFx0XHR2ZXJ0ZXgueCA9IHZlcnRleEJ1ZmZlclsgaSArIDAgXTtcblx0XHRcdHZlcnRleC55ID0gdmVydGV4QnVmZmVyWyBpICsgMSBdO1xuXHRcdFx0dmVydGV4LnogPSB2ZXJ0ZXhCdWZmZXJbIGkgKyAyIF07XG5cblx0XHRcdHZhciB1ID0gYXppbXV0aCggdmVydGV4ICkgLyAyIC8gTWF0aC5QSSArIDAuNTtcblx0XHRcdHZhciB2ID0gaW5jbGluYXRpb24oIHZlcnRleCApIC8gTWF0aC5QSSArIDAuNTtcblx0XHRcdHV2QnVmZmVyLnB1c2goIHUsIDEgLSB2ICk7XG5cblx0XHR9XG5cblx0XHRjb3JyZWN0VVZzKCk7XG5cblx0XHRjb3JyZWN0U2VhbSgpO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBjb3JyZWN0U2VhbSgpIHtcblxuXHRcdC8vIGhhbmRsZSBjYXNlIHdoZW4gZmFjZSBzdHJhZGRsZXMgdGhlIHNlYW0sIHNlZSAjMzI2OVxuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdXZCdWZmZXIubGVuZ3RoOyBpICs9IDYgKSB7XG5cblx0XHRcdC8vIHV2IGRhdGEgb2YgYSBzaW5nbGUgZmFjZVxuXG5cdFx0XHR2YXIgeDAgPSB1dkJ1ZmZlclsgaSArIDAgXTtcblx0XHRcdHZhciB4MSA9IHV2QnVmZmVyWyBpICsgMiBdO1xuXHRcdFx0dmFyIHgyID0gdXZCdWZmZXJbIGkgKyA0IF07XG5cblx0XHRcdHZhciBtYXggPSBNYXRoLm1heCggeDAsIHgxLCB4MiApO1xuXHRcdFx0dmFyIG1pbiA9IE1hdGgubWluKCB4MCwgeDEsIHgyICk7XG5cblx0XHRcdC8vIDAuOSBpcyBzb21ld2hhdCBhcmJpdHJhcnlcblxuXHRcdFx0aWYgKCBtYXggPiAwLjkgJiYgbWluIDwgMC4xICkge1xuXG5cdFx0XHRcdGlmICggeDAgPCAwLjIgKSB1dkJ1ZmZlclsgaSArIDAgXSArPSAxO1xuXHRcdFx0XHRpZiAoIHgxIDwgMC4yICkgdXZCdWZmZXJbIGkgKyAyIF0gKz0gMTtcblx0XHRcdFx0aWYgKCB4MiA8IDAuMiApIHV2QnVmZmVyWyBpICsgNCBdICs9IDE7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gcHVzaFZlcnRleCggdmVydGV4ICkge1xuXG5cdFx0dmVydGV4QnVmZmVyLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gZ2V0VmVydGV4QnlJbmRleCggaW5kZXgsIHZlcnRleCApIHtcblxuXHRcdHZhciBzdHJpZGUgPSBpbmRleCAqIDM7XG5cblx0XHR2ZXJ0ZXgueCA9IHZlcnRpY2VzWyBzdHJpZGUgKyAwIF07XG5cdFx0dmVydGV4LnkgPSB2ZXJ0aWNlc1sgc3RyaWRlICsgMSBdO1xuXHRcdHZlcnRleC56ID0gdmVydGljZXNbIHN0cmlkZSArIDIgXTtcblxuXHR9XG5cblx0ZnVuY3Rpb24gY29ycmVjdFVWcygpIHtcblxuXHRcdHZhciBhID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgYiA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIGMgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0dmFyIGNlbnRyb2lkID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHZhciB1dkEgPSBuZXcgVmVjdG9yMigpO1xuXHRcdHZhciB1dkIgPSBuZXcgVmVjdG9yMigpO1xuXHRcdHZhciB1dkMgPSBuZXcgVmVjdG9yMigpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBqID0gMDsgaSA8IHZlcnRleEJ1ZmZlci5sZW5ndGg7IGkgKz0gOSwgaiArPSA2ICkge1xuXG5cdFx0XHRhLnNldCggdmVydGV4QnVmZmVyWyBpICsgMCBdLCB2ZXJ0ZXhCdWZmZXJbIGkgKyAxIF0sIHZlcnRleEJ1ZmZlclsgaSArIDIgXSApO1xuXHRcdFx0Yi5zZXQoIHZlcnRleEJ1ZmZlclsgaSArIDMgXSwgdmVydGV4QnVmZmVyWyBpICsgNCBdLCB2ZXJ0ZXhCdWZmZXJbIGkgKyA1IF0gKTtcblx0XHRcdGMuc2V0KCB2ZXJ0ZXhCdWZmZXJbIGkgKyA2IF0sIHZlcnRleEJ1ZmZlclsgaSArIDcgXSwgdmVydGV4QnVmZmVyWyBpICsgOCBdICk7XG5cblx0XHRcdHV2QS5zZXQoIHV2QnVmZmVyWyBqICsgMCBdLCB1dkJ1ZmZlclsgaiArIDEgXSApO1xuXHRcdFx0dXZCLnNldCggdXZCdWZmZXJbIGogKyAyIF0sIHV2QnVmZmVyWyBqICsgMyBdICk7XG5cdFx0XHR1dkMuc2V0KCB1dkJ1ZmZlclsgaiArIDQgXSwgdXZCdWZmZXJbIGogKyA1IF0gKTtcblxuXHRcdFx0Y2VudHJvaWQuY29weSggYSApLmFkZCggYiApLmFkZCggYyApLmRpdmlkZVNjYWxhciggMyApO1xuXG5cdFx0XHR2YXIgYXppID0gYXppbXV0aCggY2VudHJvaWQgKTtcblxuXHRcdFx0Y29ycmVjdFVWKCB1dkEsIGogKyAwLCBhLCBhemkgKTtcblx0XHRcdGNvcnJlY3RVViggdXZCLCBqICsgMiwgYiwgYXppICk7XG5cdFx0XHRjb3JyZWN0VVYoIHV2QywgaiArIDQsIGMsIGF6aSApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBjb3JyZWN0VVYoIHV2LCBzdHJpZGUsIHZlY3RvciwgYXppbXV0aCApIHtcblxuXHRcdGlmICggKCBhemltdXRoIDwgMCApICYmICggdXYueCA9PT0gMSApICkge1xuXG5cdFx0XHR1dkJ1ZmZlclsgc3RyaWRlIF0gPSB1di54IC0gMTtcblxuXHRcdH1cblxuXHRcdGlmICggKCB2ZWN0b3IueCA9PT0gMCApICYmICggdmVjdG9yLnogPT09IDAgKSApIHtcblxuXHRcdFx0dXZCdWZmZXJbIHN0cmlkZSBdID0gYXppbXV0aCAvIDIgLyBNYXRoLlBJICsgMC41O1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBBbmdsZSBhcm91bmQgdGhlIFkgYXhpcywgY291bnRlci1jbG9ja3dpc2Ugd2hlbiBsb29raW5nIGZyb20gYWJvdmUuXG5cblx0ZnVuY3Rpb24gYXppbXV0aCggdmVjdG9yICkge1xuXG5cdFx0cmV0dXJuIE1hdGguYXRhbjIoIHZlY3Rvci56LCAtIHZlY3Rvci54ICk7XG5cblx0fVxuXG5cblx0Ly8gQW5nbGUgYWJvdmUgdGhlIFhaIHBsYW5lLlxuXG5cdGZ1bmN0aW9uIGluY2xpbmF0aW9uKCB2ZWN0b3IgKSB7XG5cblx0XHRyZXR1cm4gTWF0aC5hdGFuMiggLSB2ZWN0b3IueSwgTWF0aC5zcXJ0KCAoIHZlY3Rvci54ICogdmVjdG9yLnggKSArICggdmVjdG9yLnogKiB2ZWN0b3IueiApICkgKTtcblxuXHR9XG5cbn1cblxuUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBvbHloZWRyb25CdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIHRpbW90aHlwcmF0bGV5IC8gaHR0cHM6Ly9naXRodWIuY29tL3RpbW90aHlwcmF0bGV5XG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbi8vIFRldHJhaGVkcm9uR2VvbWV0cnlcblxuZnVuY3Rpb24gVGV0cmFoZWRyb25HZW9tZXRyeSggcmFkaXVzLCBkZXRhaWwgKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdUZXRyYWhlZHJvbkdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IFRldHJhaGVkcm9uQnVmZmVyR2VvbWV0cnkoIHJhZGl1cywgZGV0YWlsICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuVGV0cmFoZWRyb25HZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcblRldHJhaGVkcm9uR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVGV0cmFoZWRyb25HZW9tZXRyeTtcblxuLy8gVGV0cmFoZWRyb25CdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBUZXRyYWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApIHtcblxuXHR2YXIgdmVydGljZXMgPSBbXG5cdFx0MSwgIDEsICAxLCAgIC0gMSwgLSAxLCAgMSwgICAtIDEsICAxLCAtIDEsICAgIDEsIC0gMSwgLSAxXG5cdF07XG5cblx0dmFyIGluZGljZXMgPSBbXG5cdFx0MiwgIDEsICAwLCAgICAwLCAgMywgIDIsICAgIDEsICAzLCAgMCwgICAgMiwgIDMsICAxXG5cdF07XG5cblx0UG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMsIHZlcnRpY2VzLCBpbmRpY2VzLCByYWRpdXMsIGRldGFpbCApO1xuXG5cdHRoaXMudHlwZSA9ICdUZXRyYWhlZHJvbkJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxufVxuXG5UZXRyYWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIFBvbHloZWRyb25CdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcblRldHJhaGVkcm9uQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVGV0cmFoZWRyb25CdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIHRpbW90aHlwcmF0bGV5IC8gaHR0cHM6Ly9naXRodWIuY29tL3RpbW90aHlwcmF0bGV5XG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbi8vIE9jdGFoZWRyb25HZW9tZXRyeVxuXG5mdW5jdGlvbiBPY3RhaGVkcm9uR2VvbWV0cnkoIHJhZGl1cywgZGV0YWlsICkge1xuXG5cdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnT2N0YWhlZHJvbkdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IE9jdGFoZWRyb25CdWZmZXJHZW9tZXRyeSggcmFkaXVzLCBkZXRhaWwgKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5PY3RhaGVkcm9uR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5PY3RhaGVkcm9uR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gT2N0YWhlZHJvbkdlb21ldHJ5O1xuXG4vLyBPY3RhaGVkcm9uQnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gT2N0YWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApIHtcblxuXHR2YXIgdmVydGljZXMgPSBbXG5cdFx0MSwgMCwgMCwgICAtIDEsIDAsIDAsICAgIDAsIDEsIDAsICAgIDAsIC0gMSwgMCwgICAgMCwgMCwgMSwgICAgMCwgMCwgLSAxXG5cdF07XG5cblx0dmFyIGluZGljZXMgPSBbXG5cdFx0MCwgMiwgNCwgICAgMCwgNCwgMywgICAgMCwgMywgNSwgICAgMCwgNSwgMiwgICAgMSwgMiwgNSwgICAgMSwgNSwgMywgICAgMSwgMywgNCwgICAgMSwgNCwgMlxuXHRdO1xuXG5cdFBvbHloZWRyb25CdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzLCB2ZXJ0aWNlcywgaW5kaWNlcywgcmFkaXVzLCBkZXRhaWwgKTtcblxuXHR0aGlzLnR5cGUgPSAnT2N0YWhlZHJvbkJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxufVxuXG5PY3RhaGVkcm9uQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuT2N0YWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IE9jdGFoZWRyb25CdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIHRpbW90aHlwcmF0bGV5IC8gaHR0cHM6Ly9naXRodWIuY29tL3RpbW90aHlwcmF0bGV5XG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbi8vIEljb3NhaGVkcm9uR2VvbWV0cnlcblxuZnVuY3Rpb24gSWNvc2FoZWRyb25HZW9tZXRyeSggcmFkaXVzLCBkZXRhaWwgKSB7XG5cbiBcdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnSWNvc2FoZWRyb25HZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdGRldGFpbDogZGV0YWlsXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBJY29zYWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cbkljb3NhaGVkcm9uR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5JY29zYWhlZHJvbkdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEljb3NhaGVkcm9uR2VvbWV0cnk7XG5cbi8vIEljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gSWNvc2FoZWRyb25CdWZmZXJHZW9tZXRyeSggcmFkaXVzLCBkZXRhaWwgKSB7XG5cblx0dmFyIHQgPSAoIDEgKyBNYXRoLnNxcnQoIDUgKSApIC8gMjtcblxuXHR2YXIgdmVydGljZXMgPSBbXG5cdFx0LSAxLCAgdCwgIDAsICAgIDEsICB0LCAgMCwgICAtIDEsIC0gdCwgIDAsICAgIDEsIC0gdCwgIDAsXG5cdFx0IDAsIC0gMSwgIHQsICAgIDAsICAxLCAgdCwgICAgMCwgLSAxLCAtIHQsICAgIDAsICAxLCAtIHQsXG5cdFx0IHQsICAwLCAtIDEsICAgIHQsICAwLCAgMSwgICAtIHQsICAwLCAtIDEsICAgLSB0LCAgMCwgIDFcblx0XTtcblxuXHR2YXIgaW5kaWNlcyA9IFtcblx0XHQgMCwgMTEsICA1LCAgICAwLCAgNSwgIDEsICAgIDAsICAxLCAgNywgICAgMCwgIDcsIDEwLCAgICAwLCAxMCwgMTEsXG5cdFx0IDEsICA1LCAgOSwgICAgNSwgMTEsICA0LCAgIDExLCAxMCwgIDIsICAgMTAsICA3LCAgNiwgICAgNywgIDEsICA4LFxuXHRcdCAzLCAgOSwgIDQsICAgIDMsICA0LCAgMiwgICAgMywgIDIsICA2LCAgICAzLCAgNiwgIDgsICAgIDMsICA4LCAgOSxcblx0XHQgNCwgIDksICA1LCAgICAyLCAgNCwgMTEsICAgIDYsICAyLCAxMCwgICAgOCwgIDYsICA3LCAgICA5LCAgOCwgIDFcblx0XTtcblxuXHRQb2x5aGVkcm9uQnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcywgdmVydGljZXMsIGluZGljZXMsIHJhZGl1cywgZGV0YWlsICk7XG5cblx0dGhpcy50eXBlID0gJ0ljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHRkZXRhaWw6IGRldGFpbFxuXHR9O1xuXG59XG5cbkljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuSWNvc2FoZWRyb25CdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBJY29zYWhlZHJvbkJ1ZmZlckdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3IgQWJlIFBhem9zIC8gaHR0cHM6Ly9oYW1vaWQuY29tXG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbi8vIERvZGVjYWhlZHJvbkdlb21ldHJ5XG5cbmZ1bmN0aW9uIERvZGVjYWhlZHJvbkdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApIHtcblxuXHRHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0RvZGVjYWhlZHJvbkdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0ZGV0YWlsOiBkZXRhaWxcblx0fTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IERvZGVjYWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cbkRvZGVjYWhlZHJvbkdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuRG9kZWNhaGVkcm9uR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRG9kZWNhaGVkcm9uR2VvbWV0cnk7XG5cbi8vIERvZGVjYWhlZHJvbkJ1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIERvZGVjYWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIGRldGFpbCApIHtcblxuXHR2YXIgdCA9ICggMSArIE1hdGguc3FydCggNSApICkgLyAyO1xuXHR2YXIgciA9IDEgLyB0O1xuXG5cdHZhciB2ZXJ0aWNlcyA9IFtcblxuXHRcdC8vICjCsTEsIMKxMSwgwrExKVxuXHRcdC0gMSwgLSAxLCAtIDEsICAgIC0gMSwgLSAxLCAgMSxcblx0XHQtIDEsICAxLCAtIDEsICAgIC0gMSwgIDEsICAxLFxuXHRcdCAgMSwgLSAxLCAtIDEsICAgICAxLCAtIDEsICAxLFxuXHRcdCAgMSwgIDEsIC0gMSwgICAgIDEsICAxLCAgMSxcblxuXHRcdC8vICgwLCDCsTEvz4YsIMKxz4YpXG5cdFx0IDAsIC0gciwgLSB0LCAgICAgMCwgLSByLCAgdCxcblx0XHQgMCwgIHIsIC0gdCwgICAgIDAsICByLCAgdCxcblxuXHRcdC8vICjCsTEvz4YsIMKxz4YsIDApXG5cdFx0LSByLCAtIHQsICAwLCAgICAtIHIsICB0LCAgMCxcblx0XHQgciwgLSB0LCAgMCwgICAgIHIsICB0LCAgMCxcblxuXHRcdC8vICjCsc+GLCAwLCDCsTEvz4YpXG5cdFx0LSB0LCAgMCwgLSByLCAgICAgdCwgIDAsIC0gcixcblx0XHQtIHQsICAwLCAgciwgICAgIHQsICAwLCAgclxuXHRdO1xuXG5cdHZhciBpbmRpY2VzID0gW1xuXHRcdCAzLCAxMSwgIDcsICAgICAgMywgIDcsIDE1LCAgICAgIDMsIDE1LCAxMyxcblx0XHQgNywgMTksIDE3LCAgICAgIDcsIDE3LCAgNiwgICAgICA3LCAgNiwgMTUsXG5cdFx0MTcsICA0LCAgOCwgICAgIDE3LCAgOCwgMTAsICAgICAxNywgMTAsICA2LFxuXHRcdCA4LCAgMCwgMTYsICAgICAgOCwgMTYsICAyLCAgICAgIDgsICAyLCAxMCxcblx0XHQgMCwgMTIsICAxLCAgICAgIDAsICAxLCAxOCwgICAgICAwLCAxOCwgMTYsXG5cdFx0IDYsIDEwLCAgMiwgICAgICA2LCAgMiwgMTMsICAgICAgNiwgMTMsIDE1LFxuXHRcdCAyLCAxNiwgMTgsICAgICAgMiwgMTgsICAzLCAgICAgIDIsICAzLCAxMyxcblx0XHQxOCwgIDEsICA5LCAgICAgMTgsICA5LCAxMSwgICAgIDE4LCAxMSwgIDMsXG5cdFx0IDQsIDE0LCAxMiwgICAgICA0LCAxMiwgIDAsICAgICAgNCwgIDAsICA4LFxuXHRcdDExLCAgOSwgIDUsICAgICAxMSwgIDUsIDE5LCAgICAgMTEsIDE5LCAgNyxcblx0XHQxOSwgIDUsIDE0LCAgICAgMTksIDE0LCAgNCwgICAgIDE5LCAgNCwgMTcsXG5cdFx0IDEsIDEyLCAxNCwgICAgICAxLCAxNCwgIDUsICAgICAgMSwgIDUsICA5XG5cdF07XG5cblx0UG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMsIHZlcnRpY2VzLCBpbmRpY2VzLCByYWRpdXMsIGRldGFpbCApO1xuXG5cdHRoaXMudHlwZSA9ICdEb2RlY2FoZWRyb25CdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdGRldGFpbDogZGV0YWlsXG5cdH07XG5cbn1cblxuRG9kZWNhaGVkcm9uQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggUG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuRG9kZWNhaGVkcm9uQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRG9kZWNhaGVkcm9uQnVmZmVyR2VvbWV0cnk7XG5cbi8qKlxuICogQGF1dGhvciBvb3Ntb3hpZWNvZGUgLyBodHRwczovL2dpdGh1Yi5jb20vb29zbW94aWVjb2RlXG4gKiBAYXV0aG9yIFdlc3RMYW5nbGV5IC8gaHR0cHM6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwczovL2dpdGh1Yi5jb20veno4NVxuICogQGF1dGhvciBtaW5pbmdvbGQgLyBodHRwczovL2dpdGh1Yi5jb20vbWluaW5nb2xkXG4gKiBAYXV0aG9yIGpvbm9icjEgLyBodHRwczovL2dpdGh1Yi5jb20vam9ub2JyMVxuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqXG4gKi9cblxuLy8gVHViZUdlb21ldHJ5XG5cbmZ1bmN0aW9uIFR1YmVHZW9tZXRyeSggcGF0aCwgdHVidWxhclNlZ21lbnRzLCByYWRpdXMsIHJhZGlhbFNlZ21lbnRzLCBjbG9zZWQsIHRhcGVyICkge1xuXG5cdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVHViZUdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cGF0aDogcGF0aCxcblx0XHR0dWJ1bGFyU2VnbWVudHM6IHR1YnVsYXJTZWdtZW50cyxcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHRyYWRpYWxTZWdtZW50czogcmFkaWFsU2VnbWVudHMsXG5cdFx0Y2xvc2VkOiBjbG9zZWRcblx0fTtcblxuXHRpZiAoIHRhcGVyICE9PSB1bmRlZmluZWQgKSBjb25zb2xlLndhcm4oICdUSFJFRS5UdWJlR2VvbWV0cnk6IHRhcGVyIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdHZhciBidWZmZXJHZW9tZXRyeSA9IG5ldyBUdWJlQnVmZmVyR2VvbWV0cnkoIHBhdGgsIHR1YnVsYXJTZWdtZW50cywgcmFkaXVzLCByYWRpYWxTZWdtZW50cywgY2xvc2VkICk7XG5cblx0Ly8gZXhwb3NlIGludGVybmFsc1xuXG5cdHRoaXMudGFuZ2VudHMgPSBidWZmZXJHZW9tZXRyeS50YW5nZW50cztcblx0dGhpcy5ub3JtYWxzID0gYnVmZmVyR2VvbWV0cnkubm9ybWFscztcblx0dGhpcy5iaW5vcm1hbHMgPSBidWZmZXJHZW9tZXRyeS5iaW5vcm1hbHM7XG5cblx0Ly8gY3JlYXRlIGdlb21ldHJ5XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIGJ1ZmZlckdlb21ldHJ5ICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cblR1YmVHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcblR1YmVHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBUdWJlR2VvbWV0cnk7XG5cbi8vIFR1YmVCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBUdWJlQnVmZmVyR2VvbWV0cnkoIHBhdGgsIHR1YnVsYXJTZWdtZW50cywgcmFkaXVzLCByYWRpYWxTZWdtZW50cywgY2xvc2VkICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVHViZUJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cGF0aDogcGF0aCxcblx0XHR0dWJ1bGFyU2VnbWVudHM6IHR1YnVsYXJTZWdtZW50cyxcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHRyYWRpYWxTZWdtZW50czogcmFkaWFsU2VnbWVudHMsXG5cdFx0Y2xvc2VkOiBjbG9zZWRcblx0fTtcblxuXHR0dWJ1bGFyU2VnbWVudHMgPSB0dWJ1bGFyU2VnbWVudHMgfHwgNjQ7XG5cdHJhZGl1cyA9IHJhZGl1cyB8fCAxO1xuXHRyYWRpYWxTZWdtZW50cyA9IHJhZGlhbFNlZ21lbnRzIHx8IDg7XG5cdGNsb3NlZCA9IGNsb3NlZCB8fCBmYWxzZTtcblxuXHR2YXIgZnJhbWVzID0gcGF0aC5jb21wdXRlRnJlbmV0RnJhbWVzKCB0dWJ1bGFyU2VnbWVudHMsIGNsb3NlZCApO1xuXG5cdC8vIGV4cG9zZSBpbnRlcm5hbHNcblxuXHR0aGlzLnRhbmdlbnRzID0gZnJhbWVzLnRhbmdlbnRzO1xuXHR0aGlzLm5vcm1hbHMgPSBmcmFtZXMubm9ybWFscztcblx0dGhpcy5iaW5vcm1hbHMgPSBmcmFtZXMuYmlub3JtYWxzO1xuXG5cdC8vIGhlbHBlciB2YXJpYWJsZXNcblxuXHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciB1diA9IG5ldyBWZWN0b3IyKCk7XG5cblx0dmFyIGksIGo7XG5cblx0Ly8gYnVmZmVyXG5cblx0dmFyIHZlcnRpY2VzID0gW107XG5cdHZhciBub3JtYWxzID0gW107XG5cdHZhciB1dnMgPSBbXTtcblx0dmFyIGluZGljZXMgPSBbXTtcblxuXHQvLyBjcmVhdGUgYnVmZmVyIGRhdGFcblxuXHRnZW5lcmF0ZUJ1ZmZlckRhdGEoKTtcblxuXHQvLyBidWlsZCBnZW9tZXRyeVxuXG5cdHRoaXMuc2V0SW5kZXgoIGluZGljZXMgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0aWNlcywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAnbm9ybWFsJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG5vcm1hbHMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHV2cywgMiApICk7XG5cblx0Ly8gZnVuY3Rpb25zXG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVCdWZmZXJEYXRhKCkge1xuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCB0dWJ1bGFyU2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdGdlbmVyYXRlU2VnbWVudCggaSApO1xuXG5cdFx0fVxuXG5cdFx0Ly8gaWYgdGhlIGdlb21ldHJ5IGlzIG5vdCBjbG9zZWQsIGdlbmVyYXRlIHRoZSBsYXN0IHJvdyBvZiB2ZXJ0aWNlcyBhbmQgbm9ybWFsc1xuXHRcdC8vIGF0IHRoZSByZWd1bGFyIHBvc2l0aW9uIG9uIHRoZSBnaXZlbiBwYXRoXG5cdFx0Ly9cblx0XHQvLyBpZiB0aGUgZ2VvbWV0cnkgaXMgY2xvc2VkLCBkdXBsaWNhdGUgdGhlIGZpcnN0IHJvdyBvZiB2ZXJ0aWNlcyBhbmQgbm9ybWFscyAodXZzIHdpbGwgZGlmZmVyKVxuXG5cdFx0Z2VuZXJhdGVTZWdtZW50KCAoIGNsb3NlZCA9PT0gZmFsc2UgKSA/IHR1YnVsYXJTZWdtZW50cyA6IDAgKTtcblxuXHRcdC8vIHV2cyBhcmUgZ2VuZXJhdGVkIGluIGEgc2VwYXJhdGUgZnVuY3Rpb24uXG5cdFx0Ly8gdGhpcyBtYWtlcyBpdCBlYXN5IGNvbXB1dGUgY29ycmVjdCB2YWx1ZXMgZm9yIGNsb3NlZCBnZW9tZXRyaWVzXG5cblx0XHRnZW5lcmF0ZVVWcygpO1xuXG5cdFx0Ly8gZmluYWxseSBjcmVhdGUgZmFjZXNcblxuXHRcdGdlbmVyYXRlSW5kaWNlcygpO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVNlZ21lbnQoIGkgKSB7XG5cblx0XHQvLyB3ZSB1c2UgZ2V0UG9pbnRBdCB0byBzYW1wbGUgZXZlbmx5IGRpc3RyaWJ1dGVkIHBvaW50cyBmcm9tIHRoZSBnaXZlbiBwYXRoXG5cblx0XHR2YXIgUCA9IHBhdGguZ2V0UG9pbnRBdCggaSAvIHR1YnVsYXJTZWdtZW50cyApO1xuXG5cdFx0Ly8gcmV0cmlldmUgY29ycmVzcG9uZGluZyBub3JtYWwgYW5kIGJpbm9ybWFsXG5cblx0XHR2YXIgTiA9IGZyYW1lcy5ub3JtYWxzWyBpIF07XG5cdFx0dmFyIEIgPSBmcmFtZXMuYmlub3JtYWxzWyBpIF07XG5cblx0XHQvLyBnZW5lcmF0ZSBub3JtYWxzIGFuZCB2ZXJ0aWNlcyBmb3IgdGhlIGN1cnJlbnQgc2VnbWVudFxuXG5cdFx0Zm9yICggaiA9IDA7IGogPD0gcmFkaWFsU2VnbWVudHM7IGogKysgKSB7XG5cblx0XHRcdHZhciB2ID0gaiAvIHJhZGlhbFNlZ21lbnRzICogTWF0aC5QSSAqIDI7XG5cblx0XHRcdHZhciBzaW4gPSAgIE1hdGguc2luKCB2ICk7XG5cdFx0XHR2YXIgY29zID0gLSBNYXRoLmNvcyggdiApO1xuXG5cdFx0XHQvLyBub3JtYWxcblxuXHRcdFx0bm9ybWFsLnggPSAoIGNvcyAqIE4ueCArIHNpbiAqIEIueCApO1xuXHRcdFx0bm9ybWFsLnkgPSAoIGNvcyAqIE4ueSArIHNpbiAqIEIueSApO1xuXHRcdFx0bm9ybWFsLnogPSAoIGNvcyAqIE4ueiArIHNpbiAqIEIueiApO1xuXHRcdFx0bm9ybWFsLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHRub3JtYWxzLnB1c2goIG5vcm1hbC54LCBub3JtYWwueSwgbm9ybWFsLnogKTtcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHZlcnRleC54ID0gUC54ICsgcmFkaXVzICogbm9ybWFsLng7XG5cdFx0XHR2ZXJ0ZXgueSA9IFAueSArIHJhZGl1cyAqIG5vcm1hbC55O1xuXHRcdFx0dmVydGV4LnogPSBQLnogKyByYWRpdXMgKiBub3JtYWwuejtcblxuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZUluZGljZXMoKSB7XG5cblx0XHRmb3IgKCBqID0gMTsgaiA8PSB0dWJ1bGFyU2VnbWVudHM7IGogKysgKSB7XG5cblx0XHRcdGZvciAoIGkgPSAxOyBpIDw9IHJhZGlhbFNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0XHRcdHZhciBhID0gKCByYWRpYWxTZWdtZW50cyArIDEgKSAqICggaiAtIDEgKSArICggaSAtIDEgKTtcblx0XHRcdFx0dmFyIGIgPSAoIHJhZGlhbFNlZ21lbnRzICsgMSApICogaiArICggaSAtIDEgKTtcblx0XHRcdFx0dmFyIGMgPSAoIHJhZGlhbFNlZ21lbnRzICsgMSApICogaiArIGk7XG5cdFx0XHRcdHZhciBkID0gKCByYWRpYWxTZWdtZW50cyArIDEgKSAqICggaiAtIDEgKSArIGk7XG5cblx0XHRcdFx0Ly8gZmFjZXNcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGEsIGIsIGQgKTtcblx0XHRcdFx0aW5kaWNlcy5wdXNoKCBiLCBjLCBkICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVVVnMoKSB7XG5cblx0XHRmb3IgKCBpID0gMDsgaSA8PSB0dWJ1bGFyU2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdGZvciAoIGogPSAwOyBqIDw9IHJhZGlhbFNlZ21lbnRzOyBqICsrICkge1xuXG5cdFx0XHRcdHV2LnggPSBpIC8gdHVidWxhclNlZ21lbnRzO1xuXHRcdFx0XHR1di55ID0gaiAvIHJhZGlhbFNlZ21lbnRzO1xuXG5cdFx0XHRcdHV2cy5wdXNoKCB1di54LCB1di55ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cbn1cblxuVHViZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuVHViZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR1YmVCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIG9vc21veGllY29kZVxuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqXG4gKiBiYXNlZCBvbiBodHRwOi8vd3d3LmJsYWNrcGF3bi5jb20vdGV4dHMvcHF0b3J1cy9cbiAqL1xuXG4vLyBUb3J1c0tub3RHZW9tZXRyeVxuXG5mdW5jdGlvbiBUb3J1c0tub3RHZW9tZXRyeSggcmFkaXVzLCB0dWJlLCB0dWJ1bGFyU2VnbWVudHMsIHJhZGlhbFNlZ21lbnRzLCBwLCBxLCBoZWlnaHRTY2FsZSApIHtcblxuXHRHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1RvcnVzS25vdEdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0dHViZTogdHViZSxcblx0XHR0dWJ1bGFyU2VnbWVudHM6IHR1YnVsYXJTZWdtZW50cyxcblx0XHRyYWRpYWxTZWdtZW50czogcmFkaWFsU2VnbWVudHMsXG5cdFx0cDogcCxcblx0XHRxOiBxXG5cdH07XG5cblx0aWYgKCBoZWlnaHRTY2FsZSAhPT0gdW5kZWZpbmVkICkgY29uc29sZS53YXJuKCAnVEhSRUUuVG9ydXNLbm90R2VvbWV0cnk6IGhlaWdodFNjYWxlIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFVzZSAuc2NhbGUoIHgsIHksIHogKSBpbnN0ZWFkLicgKTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IFRvcnVzS25vdEJ1ZmZlckdlb21ldHJ5KCByYWRpdXMsIHR1YmUsIHR1YnVsYXJTZWdtZW50cywgcmFkaWFsU2VnbWVudHMsIHAsIHEgKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5Ub3J1c0tub3RHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcblRvcnVzS25vdEdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFRvcnVzS25vdEdlb21ldHJ5O1xuXG4vLyBUb3J1c0tub3RCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBUb3J1c0tub3RCdWZmZXJHZW9tZXRyeSggcmFkaXVzLCB0dWJlLCB0dWJ1bGFyU2VnbWVudHMsIHJhZGlhbFNlZ21lbnRzLCBwLCBxICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVG9ydXNLbm90QnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHR0dWJlOiB0dWJlLFxuXHRcdHR1YnVsYXJTZWdtZW50czogdHVidWxhclNlZ21lbnRzLFxuXHRcdHJhZGlhbFNlZ21lbnRzOiByYWRpYWxTZWdtZW50cyxcblx0XHRwOiBwLFxuXHRcdHE6IHFcblx0fTtcblxuXHRyYWRpdXMgPSByYWRpdXMgfHwgMTAwO1xuXHR0dWJlID0gdHViZSB8fCA0MDtcblx0dHVidWxhclNlZ21lbnRzID0gTWF0aC5mbG9vciggdHVidWxhclNlZ21lbnRzICkgfHwgNjQ7XG5cdHJhZGlhbFNlZ21lbnRzID0gTWF0aC5mbG9vciggcmFkaWFsU2VnbWVudHMgKSB8fCA4O1xuXHRwID0gcCB8fCAyO1xuXHRxID0gcSB8fCAzO1xuXG5cdC8vIGJ1ZmZlcnNcblxuXHR2YXIgaW5kaWNlcyA9IFtdO1xuXHR2YXIgdmVydGljZXMgPSBbXTtcblx0dmFyIG5vcm1hbHMgPSBbXTtcblx0dmFyIHV2cyA9IFtdO1xuXG5cdC8vIGhlbHBlciB2YXJpYWJsZXNcblxuXHR2YXIgaSwgajtcblxuXHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0dmFyIFAxID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIFAyID0gbmV3IFZlY3RvcjMoKTtcblxuXHR2YXIgQiA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciBUID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIE4gPSBuZXcgVmVjdG9yMygpO1xuXG5cdC8vIGdlbmVyYXRlIHZlcnRpY2VzLCBub3JtYWxzIGFuZCB1dnNcblxuXHRmb3IgKCBpID0gMDsgaSA8PSB0dWJ1bGFyU2VnbWVudHM7ICsrIGkgKSB7XG5cblx0XHQvLyB0aGUgcmFkaWFuIFwidVwiIGlzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBwb3NpdGlvbiBvbiB0aGUgdG9ydXMgY3VydmUgb2YgdGhlIGN1cnJlbnQgdHVidWxhciBzZWdlbWVudFxuXG5cdFx0dmFyIHUgPSBpIC8gdHVidWxhclNlZ21lbnRzICogcCAqIE1hdGguUEkgKiAyO1xuXG5cdFx0Ly8gbm93IHdlIGNhbGN1bGF0ZSB0d28gcG9pbnRzLiBQMSBpcyBvdXIgY3VycmVudCBwb3NpdGlvbiBvbiB0aGUgY3VydmUsIFAyIGlzIGEgbGl0dGxlIGZhcnRoZXIgYWhlYWQuXG5cdFx0Ly8gdGhlc2UgcG9pbnRzIGFyZSB1c2VkIHRvIGNyZWF0ZSBhIHNwZWNpYWwgXCJjb29yZGluYXRlIHNwYWNlXCIsIHdoaWNoIGlzIG5lY2Vzc2FyeSB0byBjYWxjdWxhdGUgdGhlIGNvcnJlY3QgdmVydGV4IHBvc2l0aW9uc1xuXG5cdFx0Y2FsY3VsYXRlUG9zaXRpb25PbkN1cnZlKCB1LCBwLCBxLCByYWRpdXMsIFAxICk7XG5cdFx0Y2FsY3VsYXRlUG9zaXRpb25PbkN1cnZlKCB1ICsgMC4wMSwgcCwgcSwgcmFkaXVzLCBQMiApO1xuXG5cdFx0Ly8gY2FsY3VsYXRlIG9ydGhvbm9ybWFsIGJhc2lzXG5cblx0XHRULnN1YlZlY3RvcnMoIFAyLCBQMSApO1xuXHRcdE4uYWRkVmVjdG9ycyggUDIsIFAxICk7XG5cdFx0Qi5jcm9zc1ZlY3RvcnMoIFQsIE4gKTtcblx0XHROLmNyb3NzVmVjdG9ycyggQiwgVCApO1xuXG5cdFx0Ly8gbm9ybWFsaXplIEIsIE4uIFQgY2FuIGJlIGlnbm9yZWQsIHdlIGRvbid0IHVzZSBpdFxuXG5cdFx0Qi5ub3JtYWxpemUoKTtcblx0XHROLm5vcm1hbGl6ZSgpO1xuXG5cdFx0Zm9yICggaiA9IDA7IGogPD0gcmFkaWFsU2VnbWVudHM7ICsrIGogKSB7XG5cblx0XHRcdC8vIG5vdyBjYWxjdWxhdGUgdGhlIHZlcnRpY2VzLiB0aGV5IGFyZSBub3RoaW5nIG1vcmUgdGhhbiBhbiBleHRydXNpb24gb2YgdGhlIHRvcnVzIGN1cnZlLlxuXHRcdFx0Ly8gYmVjYXVzZSB3ZSBleHRydWRlIGEgc2hhcGUgaW4gdGhlIHh5LXBsYW5lLCB0aGVyZSBpcyBubyBuZWVkIHRvIGNhbGN1bGF0ZSBhIHotdmFsdWUuXG5cblx0XHRcdHZhciB2ID0gaiAvIHJhZGlhbFNlZ21lbnRzICogTWF0aC5QSSAqIDI7XG5cdFx0XHR2YXIgY3ggPSAtIHR1YmUgKiBNYXRoLmNvcyggdiApO1xuXHRcdFx0dmFyIGN5ID0gdHViZSAqIE1hdGguc2luKCB2ICk7XG5cblx0XHRcdC8vIG5vdyBjYWxjdWxhdGUgdGhlIGZpbmFsIHZlcnRleCBwb3NpdGlvbi5cblx0XHRcdC8vIGZpcnN0IHdlIG9yaWVudCB0aGUgZXh0cnVzaW9uIHdpdGggb3VyIGJhc2lzIHZlY3RvcywgdGhlbiB3ZSBhZGQgaXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb24gdGhlIGN1cnZlXG5cblx0XHRcdHZlcnRleC54ID0gUDEueCArICggY3ggKiBOLnggKyBjeSAqIEIueCApO1xuXHRcdFx0dmVydGV4LnkgPSBQMS55ICsgKCBjeCAqIE4ueSArIGN5ICogQi55ICk7XG5cdFx0XHR2ZXJ0ZXgueiA9IFAxLnogKyAoIGN4ICogTi56ICsgY3kgKiBCLnogKTtcblxuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0XHQvLyBub3JtYWwgKFAxIGlzIGFsd2F5cyB0aGUgY2VudGVyL29yaWdpbiBvZiB0aGUgZXh0cnVzaW9uLCB0aHVzIHdlIGNhbiB1c2UgaXQgdG8gY2FsY3VsYXRlIHRoZSBub3JtYWwpXG5cblx0XHRcdG5vcm1hbC5zdWJWZWN0b3JzKCB2ZXJ0ZXgsIFAxICkubm9ybWFsaXplKCk7XG5cblx0XHRcdG5vcm1hbHMucHVzaCggbm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1dnMucHVzaCggaSAvIHR1YnVsYXJTZWdtZW50cyApO1xuXHRcdFx0dXZzLnB1c2goIGogLyByYWRpYWxTZWdtZW50cyApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBnZW5lcmF0ZSBpbmRpY2VzXG5cblx0Zm9yICggaiA9IDE7IGogPD0gdHVidWxhclNlZ21lbnRzOyBqICsrICkge1xuXG5cdFx0Zm9yICggaSA9IDE7IGkgPD0gcmFkaWFsU2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdC8vIGluZGljZXNcblxuXHRcdFx0dmFyIGEgPSAoIHJhZGlhbFNlZ21lbnRzICsgMSApICogKCBqIC0gMSApICsgKCBpIC0gMSApO1xuXHRcdFx0dmFyIGIgPSAoIHJhZGlhbFNlZ21lbnRzICsgMSApICogaiArICggaSAtIDEgKTtcblx0XHRcdHZhciBjID0gKCByYWRpYWxTZWdtZW50cyArIDEgKSAqIGogKyBpO1xuXHRcdFx0dmFyIGQgPSAoIHJhZGlhbFNlZ21lbnRzICsgMSApICogKCBqIC0gMSApICsgaTtcblxuXHRcdFx0Ly8gZmFjZXNcblxuXHRcdFx0aW5kaWNlcy5wdXNoKCBhLCBiLCBkICk7XG5cdFx0XHRpbmRpY2VzLnB1c2goIGIsIGMsIGQgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gYnVpbGQgZ2VvbWV0cnlcblxuXHR0aGlzLnNldEluZGV4KCBpbmRpY2VzICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ25vcm1hbCcsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBub3JtYWxzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICd1dicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB1dnMsIDIgKSApO1xuXG5cdC8vIHRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyB0aGUgY3VycmVudCBwb3NpdGlvbiBvbiB0aGUgdG9ydXMgY3VydmVcblxuXHRmdW5jdGlvbiBjYWxjdWxhdGVQb3NpdGlvbk9uQ3VydmUoIHUsIHAsIHEsIHJhZGl1cywgcG9zaXRpb24gKSB7XG5cblx0XHR2YXIgY3UgPSBNYXRoLmNvcyggdSApO1xuXHRcdHZhciBzdSA9IE1hdGguc2luKCB1ICk7XG5cdFx0dmFyIHF1T3ZlclAgPSBxIC8gcCAqIHU7XG5cdFx0dmFyIGNzID0gTWF0aC5jb3MoIHF1T3ZlclAgKTtcblxuXHRcdHBvc2l0aW9uLnggPSByYWRpdXMgKiAoIDIgKyBjcyApICogMC41ICogY3U7XG5cdFx0cG9zaXRpb24ueSA9IHJhZGl1cyAqICggMiArIGNzICkgKiBzdSAqIDAuNTtcblx0XHRwb3NpdGlvbi56ID0gcmFkaXVzICogTWF0aC5zaW4oIHF1T3ZlclAgKSAqIDAuNTtcblxuXHR9XG5cbn1cblxuVG9ydXNLbm90QnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5Ub3J1c0tub3RCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBUb3J1c0tub3RCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIG9vc21veGllY29kZVxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gVG9ydXNHZW9tZXRyeVxuXG5mdW5jdGlvbiBUb3J1c0dlb21ldHJ5KCByYWRpdXMsIHR1YmUsIHJhZGlhbFNlZ21lbnRzLCB0dWJ1bGFyU2VnbWVudHMsIGFyYyApIHtcblxuXHRHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1RvcnVzR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHR0dWJlOiB0dWJlLFxuXHRcdHJhZGlhbFNlZ21lbnRzOiByYWRpYWxTZWdtZW50cyxcblx0XHR0dWJ1bGFyU2VnbWVudHM6IHR1YnVsYXJTZWdtZW50cyxcblx0XHRhcmM6IGFyY1xuXHR9O1xuXG5cdHRoaXMuZnJvbUJ1ZmZlckdlb21ldHJ5KCBuZXcgVG9ydXNCdWZmZXJHZW9tZXRyeSggcmFkaXVzLCB0dWJlLCByYWRpYWxTZWdtZW50cywgdHVidWxhclNlZ21lbnRzLCBhcmMgKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5Ub3J1c0dlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuVG9ydXNHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBUb3J1c0dlb21ldHJ5O1xuXG4vLyBUb3J1c0J1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIFRvcnVzQnVmZmVyR2VvbWV0cnkoIHJhZGl1cywgdHViZSwgcmFkaWFsU2VnbWVudHMsIHR1YnVsYXJTZWdtZW50cywgYXJjICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVG9ydXNCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdHR1YmU6IHR1YmUsXG5cdFx0cmFkaWFsU2VnbWVudHM6IHJhZGlhbFNlZ21lbnRzLFxuXHRcdHR1YnVsYXJTZWdtZW50czogdHVidWxhclNlZ21lbnRzLFxuXHRcdGFyYzogYXJjXG5cdH07XG5cblx0cmFkaXVzID0gcmFkaXVzIHx8IDEwMDtcblx0dHViZSA9IHR1YmUgfHwgNDA7XG5cdHJhZGlhbFNlZ21lbnRzID0gTWF0aC5mbG9vciggcmFkaWFsU2VnbWVudHMgKSB8fCA4O1xuXHR0dWJ1bGFyU2VnbWVudHMgPSBNYXRoLmZsb29yKCB0dWJ1bGFyU2VnbWVudHMgKSB8fCA2O1xuXHRhcmMgPSBhcmMgfHwgTWF0aC5QSSAqIDI7XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0Ly8gaGVscGVyIHZhcmlhYmxlc1xuXG5cdHZhciBjZW50ZXIgPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0dmFyIGosIGk7XG5cblx0Ly8gZ2VuZXJhdGUgdmVydGljZXMsIG5vcm1hbHMgYW5kIHV2c1xuXG5cdGZvciAoIGogPSAwOyBqIDw9IHJhZGlhbFNlZ21lbnRzOyBqICsrICkge1xuXG5cdFx0Zm9yICggaSA9IDA7IGkgPD0gdHVidWxhclNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0XHR2YXIgdSA9IGkgLyB0dWJ1bGFyU2VnbWVudHMgKiBhcmM7XG5cdFx0XHR2YXIgdiA9IGogLyByYWRpYWxTZWdtZW50cyAqIE1hdGguUEkgKiAyO1xuXG5cdFx0XHQvLyB2ZXJ0ZXhcblxuXHRcdFx0dmVydGV4LnggPSAoIHJhZGl1cyArIHR1YmUgKiBNYXRoLmNvcyggdiApICkgKiBNYXRoLmNvcyggdSApO1xuXHRcdFx0dmVydGV4LnkgPSAoIHJhZGl1cyArIHR1YmUgKiBNYXRoLmNvcyggdiApICkgKiBNYXRoLnNpbiggdSApO1xuXHRcdFx0dmVydGV4LnogPSB0dWJlICogTWF0aC5zaW4oIHYgKTtcblxuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0XHQvLyBub3JtYWxcblxuXHRcdFx0Y2VudGVyLnggPSByYWRpdXMgKiBNYXRoLmNvcyggdSApO1xuXHRcdFx0Y2VudGVyLnkgPSByYWRpdXMgKiBNYXRoLnNpbiggdSApO1xuXHRcdFx0bm9ybWFsLnN1YlZlY3RvcnMoIHZlcnRleCwgY2VudGVyICkubm9ybWFsaXplKCk7XG5cblx0XHRcdG5vcm1hbHMucHVzaCggbm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1dnMucHVzaCggaSAvIHR1YnVsYXJTZWdtZW50cyApO1xuXHRcdFx0dXZzLnB1c2goIGogLyByYWRpYWxTZWdtZW50cyApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBnZW5lcmF0ZSBpbmRpY2VzXG5cblx0Zm9yICggaiA9IDE7IGogPD0gcmFkaWFsU2VnbWVudHM7IGogKysgKSB7XG5cblx0XHRmb3IgKCBpID0gMTsgaSA8PSB0dWJ1bGFyU2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdC8vIGluZGljZXNcblxuXHRcdFx0dmFyIGEgPSAoIHR1YnVsYXJTZWdtZW50cyArIDEgKSAqIGogKyBpIC0gMTtcblx0XHRcdHZhciBiID0gKCB0dWJ1bGFyU2VnbWVudHMgKyAxICkgKiAoIGogLSAxICkgKyBpIC0gMTtcblx0XHRcdHZhciBjID0gKCB0dWJ1bGFyU2VnbWVudHMgKyAxICkgKiAoIGogLSAxICkgKyBpO1xuXHRcdFx0dmFyIGQgPSAoIHR1YnVsYXJTZWdtZW50cyArIDEgKSAqIGogKyBpO1xuXG5cdFx0XHQvLyBmYWNlc1xuXG5cdFx0XHRpbmRpY2VzLnB1c2goIGEsIGIsIGQgKTtcblx0XHRcdGluZGljZXMucHVzaCggYiwgYywgZCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBidWlsZCBnZW9tZXRyeVxuXG5cdHRoaXMuc2V0SW5kZXgoIGluZGljZXMgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0aWNlcywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAnbm9ybWFsJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG5vcm1hbHMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHV2cywgMiApICk7XG5cbn1cblxuVG9ydXNCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcblRvcnVzQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVG9ydXNCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwOi8vd3d3LmxhYjRnYW1lcy5uZXQveno4NS9ibG9nXG4gKi9cblxudmFyIFNoYXBlVXRpbHMgPSB7XG5cblx0Ly8gY2FsY3VsYXRlIGFyZWEgb2YgdGhlIGNvbnRvdXIgcG9seWdvblxuXG5cdGFyZWE6IGZ1bmN0aW9uICggY29udG91ciApIHtcblxuXHRcdHZhciBuID0gY29udG91ci5sZW5ndGg7XG5cdFx0dmFyIGEgPSAwLjA7XG5cblx0XHRmb3IgKCB2YXIgcCA9IG4gLSAxLCBxID0gMDsgcSA8IG47IHAgPSBxICsrICkge1xuXG5cdFx0XHRhICs9IGNvbnRvdXJbIHAgXS54ICogY29udG91clsgcSBdLnkgLSBjb250b3VyWyBxIF0ueCAqIGNvbnRvdXJbIHAgXS55O1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGEgKiAwLjU7XG5cblx0fSxcblxuXHR0cmlhbmd1bGF0ZTogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHQvKipcblx0XHQgKiBUaGlzIGNvZGUgaXMgYSBxdWljayBwb3J0IG9mIGNvZGUgd3JpdHRlbiBpbiBDKysgd2hpY2ggd2FzIHN1Ym1pdHRlZCB0b1xuXHRcdCAqIGZsaXBjb2RlLmNvbSBieSBKb2huIFcuIFJhdGNsaWZmICAvLyBKdWx5IDIyLCAyMDAwXG5cdFx0ICogU2VlIG9yaWdpbmFsIGNvZGUgYW5kIG1vcmUgaW5mb3JtYXRpb24gaGVyZTpcblx0XHQgKiBodHRwOi8vd3d3LmZsaXBjb2RlLmNvbS9hcmNoaXZlcy9FZmZpY2llbnRfUG9seWdvbl9Ucmlhbmd1bGF0aW9uLnNodG1sXG5cdFx0ICpcblx0XHQgKiBwb3J0ZWQgdG8gYWN0aW9uc2NyaXB0IGJ5IFpldmFuIFJvc3NlclxuXHRcdCAqIHd3dy5hY3Rpb25zbmlwcGV0LmNvbVxuXHRcdCAqXG5cdFx0ICogcG9ydGVkIHRvIGphdmFzY3JpcHQgYnkgSm9zaHVhIEtvb1xuXHRcdCAqIGh0dHA6Ly93d3cubGFiNGdhbWVzLm5ldC96ejg1L2Jsb2dcblx0XHQgKlxuXHRcdCAqL1xuXG5cdFx0ZnVuY3Rpb24gc25pcCggY29udG91ciwgdSwgdiwgdywgbiwgdmVydHMgKSB7XG5cblx0XHRcdHZhciBwO1xuXHRcdFx0dmFyIGF4LCBheSwgYngsIGJ5O1xuXHRcdFx0dmFyIGN4LCBjeSwgcHgsIHB5O1xuXG5cdFx0XHRheCA9IGNvbnRvdXJbIHZlcnRzWyB1IF0gXS54O1xuXHRcdFx0YXkgPSBjb250b3VyWyB2ZXJ0c1sgdSBdIF0ueTtcblxuXHRcdFx0YnggPSBjb250b3VyWyB2ZXJ0c1sgdiBdIF0ueDtcblx0XHRcdGJ5ID0gY29udG91clsgdmVydHNbIHYgXSBdLnk7XG5cblx0XHRcdGN4ID0gY29udG91clsgdmVydHNbIHcgXSBdLng7XG5cdFx0XHRjeSA9IGNvbnRvdXJbIHZlcnRzWyB3IF0gXS55O1xuXG5cdFx0XHRpZiAoICggYnggLSBheCApICogKCBjeSAtIGF5ICkgLSAoIGJ5IC0gYXkgKSAqICggY3ggLSBheCApIDw9IDAgKSByZXR1cm4gZmFsc2U7XG5cblx0XHRcdHZhciBhWCwgYVksIGJYLCBiWSwgY1gsIGNZO1xuXHRcdFx0dmFyIGFweCwgYXB5LCBicHgsIGJweSwgY3B4LCBjcHk7XG5cdFx0XHR2YXIgY0NST1NTYXAsIGJDUk9TU2NwLCBhQ1JPU1NicDtcblxuXHRcdFx0YVggPSBjeCAtIGJ4OyAgYVkgPSBjeSAtIGJ5O1xuXHRcdFx0YlggPSBheCAtIGN4OyAgYlkgPSBheSAtIGN5O1xuXHRcdFx0Y1ggPSBieCAtIGF4OyAgY1kgPSBieSAtIGF5O1xuXG5cdFx0XHRmb3IgKCBwID0gMDsgcCA8IG47IHAgKysgKSB7XG5cblx0XHRcdFx0cHggPSBjb250b3VyWyB2ZXJ0c1sgcCBdIF0ueDtcblx0XHRcdFx0cHkgPSBjb250b3VyWyB2ZXJ0c1sgcCBdIF0ueTtcblxuXHRcdFx0XHRpZiAoICggKCBweCA9PT0gYXggKSAmJiAoIHB5ID09PSBheSApICkgfHxcblx0XHRcdFx0XHQgKCAoIHB4ID09PSBieCApICYmICggcHkgPT09IGJ5ICkgKSB8fFxuXHRcdFx0XHRcdCAoICggcHggPT09IGN4ICkgJiYgKCBweSA9PT0gY3kgKSApIClcdGNvbnRpbnVlO1xuXG5cdFx0XHRcdGFweCA9IHB4IC0gYXg7ICBhcHkgPSBweSAtIGF5O1xuXHRcdFx0XHRicHggPSBweCAtIGJ4OyAgYnB5ID0gcHkgLSBieTtcblx0XHRcdFx0Y3B4ID0gcHggLSBjeDsgIGNweSA9IHB5IC0gY3k7XG5cblx0XHRcdFx0Ly8gc2VlIGlmIHAgaXMgaW5zaWRlIHRyaWFuZ2xlIGFiY1xuXG5cdFx0XHRcdGFDUk9TU2JwID0gYVggKiBicHkgLSBhWSAqIGJweDtcblx0XHRcdFx0Y0NST1NTYXAgPSBjWCAqIGFweSAtIGNZICogYXB4O1xuXHRcdFx0XHRiQ1JPU1NjcCA9IGJYICogY3B5IC0gYlkgKiBjcHg7XG5cblx0XHRcdFx0aWYgKCAoIGFDUk9TU2JwID49IC0gTnVtYmVyLkVQU0lMT04gKSAmJiAoIGJDUk9TU2NwID49IC0gTnVtYmVyLkVQU0lMT04gKSAmJiAoIGNDUk9TU2FwID49IC0gTnVtYmVyLkVQU0lMT04gKSApIHJldHVybiBmYWxzZTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblxuXHRcdH1cblxuXHRcdC8vIHRha2VzIGluIGFuIGNvbnRvdXIgYXJyYXkgYW5kIHJldHVybnNcblxuXHRcdHJldHVybiBmdW5jdGlvbiB0cmlhbmd1bGF0ZSggY29udG91ciwgaW5kaWNlcyApIHtcblxuXHRcdFx0dmFyIG4gPSBjb250b3VyLmxlbmd0aDtcblxuXHRcdFx0aWYgKCBuIDwgMyApIHJldHVybiBudWxsO1xuXG5cdFx0XHR2YXIgcmVzdWx0ID0gW10sXG5cdFx0XHRcdHZlcnRzID0gW10sXG5cdFx0XHRcdHZlcnRJbmRpY2VzID0gW107XG5cblx0XHRcdC8qIHdlIHdhbnQgYSBjb3VudGVyLWNsb2Nrd2lzZSBwb2x5Z29uIGluIHZlcnRzICovXG5cblx0XHRcdHZhciB1LCB2LCB3O1xuXG5cdFx0XHRpZiAoIFNoYXBlVXRpbHMuYXJlYSggY29udG91ciApID4gMC4wICkge1xuXG5cdFx0XHRcdGZvciAoIHYgPSAwOyB2IDwgbjsgdiArKyApIHZlcnRzWyB2IF0gPSB2O1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGZvciAoIHYgPSAwOyB2IDwgbjsgdiArKyApIHZlcnRzWyB2IF0gPSAoIG4gLSAxICkgLSB2O1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBudiA9IG47XG5cblx0XHRcdC8qICByZW1vdmUgbnYgLSAyIHZlcnRpY2VzLCBjcmVhdGluZyAxIHRyaWFuZ2xlIGV2ZXJ5IHRpbWUgKi9cblxuXHRcdFx0dmFyIGNvdW50ID0gMiAqIG52OyAgIC8qIGVycm9yIGRldGVjdGlvbiAqL1xuXG5cdFx0XHRmb3IgKCB2ID0gbnYgLSAxOyBudiA+IDI7ICkge1xuXG5cdFx0XHRcdC8qIGlmIHdlIGxvb3AsIGl0IGlzIHByb2JhYmx5IGEgbm9uLXNpbXBsZSBwb2x5Z29uICovXG5cblx0XHRcdFx0aWYgKCAoIGNvdW50IC0tICkgPD0gMCApIHtcblxuXHRcdFx0XHRcdC8vKiogVHJpYW5ndWxhdGU6IEVSUk9SIC0gcHJvYmFibGUgYmFkIHBvbHlnb24hXG5cblx0XHRcdFx0XHQvL3Rocm93ICggXCJXYXJuaW5nLCB1bmFibGUgdG8gdHJpYW5ndWxhdGUgcG9seWdvbiFcIiApO1xuXHRcdFx0XHRcdC8vcmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0Ly8gU29tZXRpbWVzIHdhcm5pbmcgaXMgZmluZSwgZXNwZWNpYWxseSBwb2x5Z29ucyBhcmUgdHJpYW5ndWxhdGVkIGluIHJldmVyc2UuXG5cdFx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuU2hhcGVVdGlsczogVW5hYmxlIHRvIHRyaWFuZ3VsYXRlIHBvbHlnb24hIGluIHRyaWFuZ3VsYXRlKCknICk7XG5cblx0XHRcdFx0XHRpZiAoIGluZGljZXMgKSByZXR1cm4gdmVydEluZGljZXM7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0LyogdGhyZWUgY29uc2VjdXRpdmUgdmVydGljZXMgaW4gY3VycmVudCBwb2x5Z29uLCA8dSx2LHc+ICovXG5cblx0XHRcdFx0dSA9IHY7IFx0IFx0aWYgKCBudiA8PSB1ICkgdSA9IDA7ICAgICAvKiBwcmV2aW91cyAqL1xuXHRcdFx0XHR2ID0gdSArIDE7ICBpZiAoIG52IDw9IHYgKSB2ID0gMDsgICAgIC8qIG5ldyB2ICAgICovXG5cdFx0XHRcdHcgPSB2ICsgMTsgIGlmICggbnYgPD0gdyApIHcgPSAwOyAgICAgLyogbmV4dCAgICAgKi9cblxuXHRcdFx0XHRpZiAoIHNuaXAoIGNvbnRvdXIsIHUsIHYsIHcsIG52LCB2ZXJ0cyApICkge1xuXG5cdFx0XHRcdFx0dmFyIGEsIGIsIGMsIHMsIHQ7XG5cblx0XHRcdFx0XHQvKiB0cnVlIG5hbWVzIG9mIHRoZSB2ZXJ0aWNlcyAqL1xuXG5cdFx0XHRcdFx0YSA9IHZlcnRzWyB1IF07XG5cdFx0XHRcdFx0YiA9IHZlcnRzWyB2IF07XG5cdFx0XHRcdFx0YyA9IHZlcnRzWyB3IF07XG5cblx0XHRcdFx0XHQvKiBvdXRwdXQgVHJpYW5nbGUgKi9cblxuXHRcdFx0XHRcdHJlc3VsdC5wdXNoKCBbIGNvbnRvdXJbIGEgXSxcblx0XHRcdFx0XHRcdGNvbnRvdXJbIGIgXSxcblx0XHRcdFx0XHRcdGNvbnRvdXJbIGMgXSBdICk7XG5cblxuXHRcdFx0XHRcdHZlcnRJbmRpY2VzLnB1c2goIFsgdmVydHNbIHUgXSwgdmVydHNbIHYgXSwgdmVydHNbIHcgXSBdICk7XG5cblx0XHRcdFx0XHQvKiByZW1vdmUgdiBmcm9tIHRoZSByZW1haW5pbmcgcG9seWdvbiAqL1xuXG5cdFx0XHRcdFx0Zm9yICggcyA9IHYsIHQgPSB2ICsgMTsgdCA8IG52OyBzICsrLCB0ICsrICkge1xuXG5cdFx0XHRcdFx0XHR2ZXJ0c1sgcyBdID0gdmVydHNbIHQgXTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG52IC0tO1xuXG5cdFx0XHRcdFx0LyogcmVzZXQgZXJyb3IgZGV0ZWN0aW9uIGNvdW50ZXIgKi9cblxuXHRcdFx0XHRcdGNvdW50ID0gMiAqIG52O1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGluZGljZXMgKSByZXR1cm4gdmVydEluZGljZXM7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdFx0fVxuXG5cdH0gKSgpLFxuXG5cdHRyaWFuZ3VsYXRlU2hhcGU6IGZ1bmN0aW9uICggY29udG91ciwgaG9sZXMgKSB7XG5cblx0XHRmdW5jdGlvbiByZW1vdmVEdXBFbmRQdHMocG9pbnRzKSB7XG5cblx0XHRcdHZhciBsID0gcG9pbnRzLmxlbmd0aDtcblxuXHRcdFx0aWYgKCBsID4gMiAmJiBwb2ludHNbIGwgLSAxIF0uZXF1YWxzKCBwb2ludHNbIDAgXSApICkge1xuXG5cdFx0XHRcdHBvaW50cy5wb3AoKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmVtb3ZlRHVwRW5kUHRzKCBjb250b3VyICk7XG5cdFx0aG9sZXMuZm9yRWFjaCggcmVtb3ZlRHVwRW5kUHRzICk7XG5cblx0XHRmdW5jdGlvbiBwb2ludF9pbl9zZWdtZW50XzJEX2NvbGluKCBpblNlZ1B0MSwgaW5TZWdQdDIsIGluT3RoZXJQdCApIHtcblxuXHRcdFx0Ly8gaW5PdGhlclB0IG5lZWRzIHRvIGJlIGNvbGxpbmVhciB0byB0aGUgaW5TZWdtZW50XG5cdFx0XHRpZiAoIGluU2VnUHQxLnggIT09IGluU2VnUHQyLnggKSB7XG5cblx0XHRcdFx0aWYgKCBpblNlZ1B0MS54IDwgaW5TZWdQdDIueCApIHtcblxuXHRcdFx0XHRcdHJldHVyblx0KCAoIGluU2VnUHQxLnggPD0gaW5PdGhlclB0LnggKSAmJiAoIGluT3RoZXJQdC54IDw9IGluU2VnUHQyLnggKSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRyZXR1cm5cdCggKCBpblNlZ1B0Mi54IDw9IGluT3RoZXJQdC54ICkgJiYgKCBpbk90aGVyUHQueCA8PSBpblNlZ1B0MS54ICkgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0aWYgKCBpblNlZ1B0MS55IDwgaW5TZWdQdDIueSApIHtcblxuXHRcdFx0XHRcdHJldHVyblx0KCAoIGluU2VnUHQxLnkgPD0gaW5PdGhlclB0LnkgKSAmJiAoIGluT3RoZXJQdC55IDw9IGluU2VnUHQyLnkgKSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRyZXR1cm5cdCggKCBpblNlZ1B0Mi55IDw9IGluT3RoZXJQdC55ICkgJiYgKCBpbk90aGVyUHQueSA8PSBpblNlZ1B0MS55ICkgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGludGVyc2VjdF9zZWdtZW50c18yRCggaW5TZWcxUHQxLCBpblNlZzFQdDIsIGluU2VnMlB0MSwgaW5TZWcyUHQyLCBpbkV4Y2x1ZGVBZGphY2VudFNlZ3MgKSB7XG5cblx0XHRcdHZhciBzZWcxZHggPSBpblNlZzFQdDIueCAtIGluU2VnMVB0MS54LCAgIHNlZzFkeSA9IGluU2VnMVB0Mi55IC0gaW5TZWcxUHQxLnk7XG5cdFx0XHR2YXIgc2VnMmR4ID0gaW5TZWcyUHQyLnggLSBpblNlZzJQdDEueCwgICBzZWcyZHkgPSBpblNlZzJQdDIueSAtIGluU2VnMlB0MS55O1xuXG5cdFx0XHR2YXIgc2VnMXNlZzJkeCA9IGluU2VnMVB0MS54IC0gaW5TZWcyUHQxLng7XG5cdFx0XHR2YXIgc2VnMXNlZzJkeSA9IGluU2VnMVB0MS55IC0gaW5TZWcyUHQxLnk7XG5cblx0XHRcdHZhciBsaW1pdFx0XHQ9IHNlZzFkeSAqIHNlZzJkeCAtIHNlZzFkeCAqIHNlZzJkeTtcblx0XHRcdHZhciBwZXJwU2VnMVx0PSBzZWcxZHkgKiBzZWcxc2VnMmR4IC0gc2VnMWR4ICogc2VnMXNlZzJkeTtcblxuXHRcdFx0aWYgKCBNYXRoLmFicyggbGltaXQgKSA+IE51bWJlci5FUFNJTE9OICkge1xuXG5cdFx0XHRcdC8vIG5vdCBwYXJhbGxlbFxuXG5cdFx0XHRcdHZhciBwZXJwU2VnMjtcblx0XHRcdFx0aWYgKCBsaW1pdCA+IDAgKSB7XG5cblx0XHRcdFx0XHRpZiAoICggcGVycFNlZzEgPCAwICkgfHwgKCBwZXJwU2VnMSA+IGxpbWl0ICkgKSBcdFx0cmV0dXJuIFtdO1xuXHRcdFx0XHRcdHBlcnBTZWcyID0gc2VnMmR5ICogc2VnMXNlZzJkeCAtIHNlZzJkeCAqIHNlZzFzZWcyZHk7XG5cdFx0XHRcdFx0aWYgKCAoIHBlcnBTZWcyIDwgMCApIHx8ICggcGVycFNlZzIgPiBsaW1pdCApICkgXHRcdHJldHVybiBbXTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0aWYgKCAoIHBlcnBTZWcxID4gMCApIHx8ICggcGVycFNlZzEgPCBsaW1pdCApICkgXHRcdHJldHVybiBbXTtcblx0XHRcdFx0XHRwZXJwU2VnMiA9IHNlZzJkeSAqIHNlZzFzZWcyZHggLSBzZWcyZHggKiBzZWcxc2VnMmR5O1xuXHRcdFx0XHRcdGlmICggKCBwZXJwU2VnMiA+IDAgKSB8fCAoIHBlcnBTZWcyIDwgbGltaXQgKSApIFx0XHRyZXR1cm4gW107XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGkuZS4gdG8gcmVkdWNlIHJvdW5kaW5nIGVycm9yc1xuXHRcdFx0XHQvLyBpbnRlcnNlY3Rpb24gYXQgZW5kcG9pbnQgb2Ygc2VnbWVudCMxP1xuXHRcdFx0XHRpZiAoIHBlcnBTZWcyID09PSAwICkge1xuXG5cdFx0XHRcdFx0aWYgKCAoIGluRXhjbHVkZUFkamFjZW50U2VncyApICYmXG5cdFx0XHRcdFx0XHQgKCAoIHBlcnBTZWcxID09PSAwICkgfHwgKCBwZXJwU2VnMSA9PT0gbGltaXQgKSApIClcdFx0cmV0dXJuIFtdO1xuXHRcdFx0XHRcdHJldHVybiBbIGluU2VnMVB0MSBdO1xuXG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBwZXJwU2VnMiA9PT0gbGltaXQgKSB7XG5cblx0XHRcdFx0XHRpZiAoICggaW5FeGNsdWRlQWRqYWNlbnRTZWdzICkgJiZcblx0XHRcdFx0XHRcdCAoICggcGVycFNlZzEgPT09IDAgKSB8fCAoIHBlcnBTZWcxID09PSBsaW1pdCApICkgKVx0XHRyZXR1cm4gW107XG5cdFx0XHRcdFx0cmV0dXJuIFsgaW5TZWcxUHQyIF07XG5cblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBpbnRlcnNlY3Rpb24gYXQgZW5kcG9pbnQgb2Ygc2VnbWVudCMyP1xuXHRcdFx0XHRpZiAoIHBlcnBTZWcxID09PSAwIClcdFx0cmV0dXJuIFsgaW5TZWcyUHQxIF07XG5cdFx0XHRcdGlmICggcGVycFNlZzEgPT09IGxpbWl0IClcdHJldHVybiBbIGluU2VnMlB0MiBdO1xuXG5cdFx0XHRcdC8vIHJldHVybiByZWFsIGludGVyc2VjdGlvbiBwb2ludFxuXHRcdFx0XHR2YXIgZmFjdG9yU2VnMSA9IHBlcnBTZWcyIC8gbGltaXQ7XG5cdFx0XHRcdHJldHVyblx0WyB7IHg6IGluU2VnMVB0MS54ICsgZmFjdG9yU2VnMSAqIHNlZzFkeCxcblx0XHRcdFx0XHRcdFx0eTogaW5TZWcxUHQxLnkgKyBmYWN0b3JTZWcxICogc2VnMWR5IH0gXTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBwYXJhbGxlbCBvciBjb2xsaW5lYXJcblx0XHRcdFx0aWYgKCAoIHBlcnBTZWcxICE9PSAwICkgfHxcblx0XHRcdFx0XHQgKCBzZWcyZHkgKiBzZWcxc2VnMmR4ICE9PSBzZWcyZHggKiBzZWcxc2VnMmR5ICkgKSBcdFx0XHRyZXR1cm4gW107XG5cblx0XHRcdFx0Ly8gdGhleSBhcmUgY29sbGluZWFyIG9yIGRlZ2VuZXJhdGVcblx0XHRcdFx0dmFyIHNlZzFQdCA9ICggKCBzZWcxZHggPT09IDAgKSAmJiAoIHNlZzFkeSA9PT0gMCApICk7XHQvLyBzZWdtZW50MSBpcyBqdXN0IGEgcG9pbnQ/XG5cdFx0XHRcdHZhciBzZWcyUHQgPSAoICggc2VnMmR4ID09PSAwICkgJiYgKCBzZWcyZHkgPT09IDAgKSApO1x0Ly8gc2VnbWVudDIgaXMganVzdCBhIHBvaW50P1xuXHRcdFx0XHQvLyBib3RoIHNlZ21lbnRzIGFyZSBwb2ludHNcblx0XHRcdFx0aWYgKCBzZWcxUHQgJiYgc2VnMlB0ICkge1xuXG5cdFx0XHRcdFx0aWYgKCAoIGluU2VnMVB0MS54ICE9PSBpblNlZzJQdDEueCApIHx8XG5cdFx0XHRcdFx0XHQgKCBpblNlZzFQdDEueSAhPT0gaW5TZWcyUHQxLnkgKSApXHRcdHJldHVybiBbXTtcdC8vIHRoZXkgYXJlIGRpc3RpbmN0ICBwb2ludHNcblx0XHRcdFx0XHRyZXR1cm4gWyBpblNlZzFQdDEgXTsgICAgICAgICAgICAgICAgIFx0XHRcdFx0XHRcdC8vIHRoZXkgYXJlIHRoZSBzYW1lIHBvaW50XG5cblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBzZWdtZW50IzEgIGlzIGEgc2luZ2xlIHBvaW50XG5cdFx0XHRcdGlmICggc2VnMVB0ICkge1xuXG5cdFx0XHRcdFx0aWYgKCAhIHBvaW50X2luX3NlZ21lbnRfMkRfY29saW4oIGluU2VnMlB0MSwgaW5TZWcyUHQyLCBpblNlZzFQdDEgKSApXHRcdHJldHVybiBbXTtcdFx0Ly8gYnV0IG5vdCBpbiBzZWdtZW50IzJcblx0XHRcdFx0XHRyZXR1cm4gWyBpblNlZzFQdDEgXTtcblxuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIHNlZ21lbnQjMiAgaXMgYSBzaW5nbGUgcG9pbnRcblx0XHRcdFx0aWYgKCBzZWcyUHQgKSB7XG5cblx0XHRcdFx0XHRpZiAoICEgcG9pbnRfaW5fc2VnbWVudF8yRF9jb2xpbiggaW5TZWcxUHQxLCBpblNlZzFQdDIsIGluU2VnMlB0MSApIClcdFx0cmV0dXJuIFtdO1x0XHQvLyBidXQgbm90IGluIHNlZ21lbnQjMVxuXHRcdFx0XHRcdHJldHVybiBbIGluU2VnMlB0MSBdO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyB0aGV5IGFyZSBjb2xsaW5lYXIgc2VnbWVudHMsIHdoaWNoIG1pZ2h0IG92ZXJsYXBcblx0XHRcdFx0dmFyIHNlZzFtaW4sIHNlZzFtYXgsIHNlZzFtaW5WYWwsIHNlZzFtYXhWYWw7XG5cdFx0XHRcdHZhciBzZWcybWluLCBzZWcybWF4LCBzZWcybWluVmFsLCBzZWcybWF4VmFsO1xuXHRcdFx0XHRpZiAoIHNlZzFkeCAhPT0gMCApIHtcblxuXHRcdFx0XHRcdC8vIHRoZSBzZWdtZW50cyBhcmUgTk9UIG9uIGEgdmVydGljYWwgbGluZVxuXHRcdFx0XHRcdGlmICggaW5TZWcxUHQxLnggPCBpblNlZzFQdDIueCApIHtcblxuXHRcdFx0XHRcdFx0c2VnMW1pbiA9IGluU2VnMVB0MTsgc2VnMW1pblZhbCA9IGluU2VnMVB0MS54O1xuXHRcdFx0XHRcdFx0c2VnMW1heCA9IGluU2VnMVB0Mjsgc2VnMW1heFZhbCA9IGluU2VnMVB0Mi54O1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0c2VnMW1pbiA9IGluU2VnMVB0Mjsgc2VnMW1pblZhbCA9IGluU2VnMVB0Mi54O1xuXHRcdFx0XHRcdFx0c2VnMW1heCA9IGluU2VnMVB0MTsgc2VnMW1heFZhbCA9IGluU2VnMVB0MS54O1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggaW5TZWcyUHQxLnggPCBpblNlZzJQdDIueCApIHtcblxuXHRcdFx0XHRcdFx0c2VnMm1pbiA9IGluU2VnMlB0MTsgc2VnMm1pblZhbCA9IGluU2VnMlB0MS54O1xuXHRcdFx0XHRcdFx0c2VnMm1heCA9IGluU2VnMlB0Mjsgc2VnMm1heFZhbCA9IGluU2VnMlB0Mi54O1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0c2VnMm1pbiA9IGluU2VnMlB0Mjsgc2VnMm1pblZhbCA9IGluU2VnMlB0Mi54O1xuXHRcdFx0XHRcdFx0c2VnMm1heCA9IGluU2VnMlB0MTsgc2VnMm1heFZhbCA9IGluU2VnMlB0MS54O1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHQvLyB0aGUgc2VnbWVudHMgYXJlIG9uIGEgdmVydGljYWwgbGluZVxuXHRcdFx0XHRcdGlmICggaW5TZWcxUHQxLnkgPCBpblNlZzFQdDIueSApIHtcblxuXHRcdFx0XHRcdFx0c2VnMW1pbiA9IGluU2VnMVB0MTsgc2VnMW1pblZhbCA9IGluU2VnMVB0MS55O1xuXHRcdFx0XHRcdFx0c2VnMW1heCA9IGluU2VnMVB0Mjsgc2VnMW1heFZhbCA9IGluU2VnMVB0Mi55O1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0c2VnMW1pbiA9IGluU2VnMVB0Mjsgc2VnMW1pblZhbCA9IGluU2VnMVB0Mi55O1xuXHRcdFx0XHRcdFx0c2VnMW1heCA9IGluU2VnMVB0MTsgc2VnMW1heFZhbCA9IGluU2VnMVB0MS55O1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggaW5TZWcyUHQxLnkgPCBpblNlZzJQdDIueSApIHtcblxuXHRcdFx0XHRcdFx0c2VnMm1pbiA9IGluU2VnMlB0MTsgc2VnMm1pblZhbCA9IGluU2VnMlB0MS55O1xuXHRcdFx0XHRcdFx0c2VnMm1heCA9IGluU2VnMlB0Mjsgc2VnMm1heFZhbCA9IGluU2VnMlB0Mi55O1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0c2VnMm1pbiA9IGluU2VnMlB0Mjsgc2VnMm1pblZhbCA9IGluU2VnMlB0Mi55O1xuXHRcdFx0XHRcdFx0c2VnMm1heCA9IGluU2VnMlB0MTsgc2VnMm1heFZhbCA9IGluU2VnMlB0MS55O1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBzZWcxbWluVmFsIDw9IHNlZzJtaW5WYWwgKSB7XG5cblx0XHRcdFx0XHRpZiAoIHNlZzFtYXhWYWwgPCAgc2VnMm1pblZhbCApXHRyZXR1cm4gW107XG5cdFx0XHRcdFx0aWYgKCBzZWcxbWF4VmFsID09PSBzZWcybWluVmFsIClcdHtcblxuXHRcdFx0XHRcdFx0aWYgKCBpbkV4Y2x1ZGVBZGphY2VudFNlZ3MgKVx0XHRyZXR1cm4gW107XG5cdFx0XHRcdFx0XHRyZXR1cm4gWyBzZWcybWluIF07XG5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBzZWcxbWF4VmFsIDw9IHNlZzJtYXhWYWwgKVx0cmV0dXJuIFsgc2VnMm1pbiwgc2VnMW1heCBdO1xuXHRcdFx0XHRcdHJldHVyblx0WyBzZWcybWluLCBzZWcybWF4IF07XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGlmICggc2VnMW1pblZhbCA+ICBzZWcybWF4VmFsIClcdHJldHVybiBbXTtcblx0XHRcdFx0XHRpZiAoIHNlZzFtaW5WYWwgPT09IHNlZzJtYXhWYWwgKVx0e1xuXG5cdFx0XHRcdFx0XHRpZiAoIGluRXhjbHVkZUFkamFjZW50U2VncyApXHRcdHJldHVybiBbXTtcblx0XHRcdFx0XHRcdHJldHVybiBbIHNlZzFtaW4gXTtcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIHNlZzFtYXhWYWwgPD0gc2VnMm1heFZhbCApXHRyZXR1cm4gWyBzZWcxbWluLCBzZWcxbWF4IF07XG5cdFx0XHRcdFx0cmV0dXJuXHRbIHNlZzFtaW4sIHNlZzJtYXggXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGlzUG9pbnRJbnNpZGVBbmdsZSggaW5WZXJ0ZXgsIGluTGVnRnJvbVB0LCBpbkxlZ1RvUHQsIGluT3RoZXJQdCApIHtcblxuXHRcdFx0Ly8gVGhlIG9yZGVyIG9mIGxlZ3MgaXMgaW1wb3J0YW50XG5cblx0XHRcdC8vIHRyYW5zbGF0aW9uIG9mIGFsbCBwb2ludHMsIHNvIHRoYXQgVmVydGV4IGlzIGF0ICgwLDApXG5cdFx0XHR2YXIgbGVnRnJvbVB0WFx0PSBpbkxlZ0Zyb21QdC54IC0gaW5WZXJ0ZXgueCwgIGxlZ0Zyb21QdFlcdD0gaW5MZWdGcm9tUHQueSAtIGluVmVydGV4Lnk7XG5cdFx0XHR2YXIgbGVnVG9QdFhcdD0gaW5MZWdUb1B0LnhcdC0gaW5WZXJ0ZXgueCwgIGxlZ1RvUHRZXHRcdD0gaW5MZWdUb1B0LnlcdC0gaW5WZXJ0ZXgueTtcblx0XHRcdHZhciBvdGhlclB0WFx0PSBpbk90aGVyUHQueFx0LSBpblZlcnRleC54LCAgb3RoZXJQdFlcdFx0PSBpbk90aGVyUHQueVx0LSBpblZlcnRleC55O1xuXG5cdFx0XHQvLyBtYWluIGFuZ2xlID4wOiA8IDE4MCBkZWcuOyAwOiAxODAgZGVnLjsgPDA6ID4gMTgwIGRlZy5cblx0XHRcdHZhciBmcm9tMnRvQW5nbGVcdD0gbGVnRnJvbVB0WCAqIGxlZ1RvUHRZIC0gbGVnRnJvbVB0WSAqIGxlZ1RvUHRYO1xuXHRcdFx0dmFyIGZyb20yb3RoZXJBbmdsZVx0PSBsZWdGcm9tUHRYICogb3RoZXJQdFkgLSBsZWdGcm9tUHRZICogb3RoZXJQdFg7XG5cblx0XHRcdGlmICggTWF0aC5hYnMoIGZyb20ydG9BbmdsZSApID4gTnVtYmVyLkVQU0lMT04gKSB7XG5cblx0XHRcdFx0Ly8gYW5nbGUgIT0gMTgwIGRlZy5cblxuXHRcdFx0XHR2YXIgb3RoZXIydG9BbmdsZVx0XHQ9IG90aGVyUHRYICogbGVnVG9QdFkgLSBvdGhlclB0WSAqIGxlZ1RvUHRYO1xuXHRcdFx0XHQvLyBjb25zb2xlLmxvZyggXCJmcm9tMnRvOiBcIiArIGZyb20ydG9BbmdsZSArIFwiLCBmcm9tMm90aGVyOiBcIiArIGZyb20yb3RoZXJBbmdsZSArIFwiLCBvdGhlcjJ0bzogXCIgKyBvdGhlcjJ0b0FuZ2xlICk7XG5cblx0XHRcdFx0aWYgKCBmcm9tMnRvQW5nbGUgPiAwICkge1xuXG5cdFx0XHRcdFx0Ly8gbWFpbiBhbmdsZSA8IDE4MCBkZWcuXG5cdFx0XHRcdFx0cmV0dXJuXHQoICggZnJvbTJvdGhlckFuZ2xlID49IDAgKSAmJiAoIG90aGVyMnRvQW5nbGUgPj0gMCApICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdC8vIG1haW4gYW5nbGUgPiAxODAgZGVnLlxuXHRcdFx0XHRcdHJldHVyblx0KCAoIGZyb20yb3RoZXJBbmdsZSA+PSAwICkgfHwgKCBvdGhlcjJ0b0FuZ2xlID49IDAgKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBhbmdsZSA9PSAxODAgZGVnLlxuXHRcdFx0XHQvLyBjb25zb2xlLmxvZyggXCJmcm9tMnRvOiAxODAgZGVnLiwgZnJvbTJvdGhlcjogXCIgKyBmcm9tMm90aGVyQW5nbGUgICk7XG5cdFx0XHRcdHJldHVyblx0KCBmcm9tMm90aGVyQW5nbGUgPiAwICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXG5cdFx0ZnVuY3Rpb24gcmVtb3ZlSG9sZXMoIGNvbnRvdXIsIGhvbGVzICkge1xuXG5cdFx0XHR2YXIgc2hhcGUgPSBjb250b3VyLmNvbmNhdCgpOyAvLyB3b3JrIG9uIHRoaXMgc2hhcGVcblx0XHRcdHZhciBob2xlO1xuXG5cdFx0XHRmdW5jdGlvbiBpc0N1dExpbmVJbnNpZGVBbmdsZXMoIGluU2hhcGVJZHgsIGluSG9sZUlkeCApIHtcblxuXHRcdFx0XHQvLyBDaGVjayBpZiBob2xlIHBvaW50IGxpZXMgd2l0aGluIGFuZ2xlIGFyb3VuZCBzaGFwZSBwb2ludFxuXHRcdFx0XHR2YXIgbGFzdFNoYXBlSWR4ID0gc2hhcGUubGVuZ3RoIC0gMTtcblxuXHRcdFx0XHR2YXIgcHJldlNoYXBlSWR4ID0gaW5TaGFwZUlkeCAtIDE7XG5cdFx0XHRcdGlmICggcHJldlNoYXBlSWR4IDwgMCApXHRcdFx0cHJldlNoYXBlSWR4ID0gbGFzdFNoYXBlSWR4O1xuXG5cdFx0XHRcdHZhciBuZXh0U2hhcGVJZHggPSBpblNoYXBlSWR4ICsgMTtcblx0XHRcdFx0aWYgKCBuZXh0U2hhcGVJZHggPiBsYXN0U2hhcGVJZHggKVx0bmV4dFNoYXBlSWR4ID0gMDtcblxuXHRcdFx0XHR2YXIgaW5zaWRlQW5nbGUgPSBpc1BvaW50SW5zaWRlQW5nbGUoIHNoYXBlWyBpblNoYXBlSWR4IF0sIHNoYXBlWyBwcmV2U2hhcGVJZHggXSwgc2hhcGVbIG5leHRTaGFwZUlkeCBdLCBob2xlWyBpbkhvbGVJZHggXSApO1xuXHRcdFx0XHRpZiAoICEgaW5zaWRlQW5nbGUgKSB7XG5cblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyggXCJWZXJ0ZXggKFNoYXBlKTogXCIgKyBpblNoYXBlSWR4ICsgXCIsIFBvaW50OiBcIiArIGhvbGVbaW5Ib2xlSWR4XS54ICsgXCIvXCIgKyBob2xlW2luSG9sZUlkeF0ueSApO1xuXHRcdFx0XHRcdHJldHVyblx0ZmFsc2U7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENoZWNrIGlmIHNoYXBlIHBvaW50IGxpZXMgd2l0aGluIGFuZ2xlIGFyb3VuZCBob2xlIHBvaW50XG5cdFx0XHRcdHZhciBsYXN0SG9sZUlkeCA9IGhvbGUubGVuZ3RoIC0gMTtcblxuXHRcdFx0XHR2YXIgcHJldkhvbGVJZHggPSBpbkhvbGVJZHggLSAxO1xuXHRcdFx0XHRpZiAoIHByZXZIb2xlSWR4IDwgMCApXHRcdFx0cHJldkhvbGVJZHggPSBsYXN0SG9sZUlkeDtcblxuXHRcdFx0XHR2YXIgbmV4dEhvbGVJZHggPSBpbkhvbGVJZHggKyAxO1xuXHRcdFx0XHRpZiAoIG5leHRIb2xlSWR4ID4gbGFzdEhvbGVJZHggKVx0bmV4dEhvbGVJZHggPSAwO1xuXG5cdFx0XHRcdGluc2lkZUFuZ2xlID0gaXNQb2ludEluc2lkZUFuZ2xlKCBob2xlWyBpbkhvbGVJZHggXSwgaG9sZVsgcHJldkhvbGVJZHggXSwgaG9sZVsgbmV4dEhvbGVJZHggXSwgc2hhcGVbIGluU2hhcGVJZHggXSApO1xuXHRcdFx0XHRpZiAoICEgaW5zaWRlQW5nbGUgKSB7XG5cblx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZyggXCJWZXJ0ZXggKEhvbGUpOiBcIiArIGluSG9sZUlkeCArIFwiLCBQb2ludDogXCIgKyBzaGFwZVtpblNoYXBlSWR4XS54ICsgXCIvXCIgKyBzaGFwZVtpblNoYXBlSWR4XS55ICk7XG5cdFx0XHRcdFx0cmV0dXJuXHRmYWxzZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuXHR0cnVlO1xuXG5cdFx0XHR9XG5cblx0XHRcdGZ1bmN0aW9uIGludGVyc2VjdHNTaGFwZUVkZ2UoIGluU2hhcGVQdCwgaW5Ib2xlUHQgKSB7XG5cblx0XHRcdFx0Ly8gY2hlY2tzIGZvciBpbnRlcnNlY3Rpb25zIHdpdGggc2hhcGUgZWRnZXNcblx0XHRcdFx0dmFyIHNJZHgsIG5leHRJZHgsIGludGVyc2VjdGlvbjtcblx0XHRcdFx0Zm9yICggc0lkeCA9IDA7IHNJZHggPCBzaGFwZS5sZW5ndGg7IHNJZHggKysgKSB7XG5cblx0XHRcdFx0XHRuZXh0SWR4ID0gc0lkeCArIDE7IG5leHRJZHggJT0gc2hhcGUubGVuZ3RoO1xuXHRcdFx0XHRcdGludGVyc2VjdGlvbiA9IGludGVyc2VjdF9zZWdtZW50c18yRCggaW5TaGFwZVB0LCBpbkhvbGVQdCwgc2hhcGVbIHNJZHggXSwgc2hhcGVbIG5leHRJZHggXSwgdHJ1ZSApO1xuXHRcdFx0XHRcdGlmICggaW50ZXJzZWN0aW9uLmxlbmd0aCA+IDAgKVx0XHRyZXR1cm5cdHRydWU7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVyblx0ZmFsc2U7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIGluZGVwSG9sZXMgPSBbXTtcblxuXHRcdFx0ZnVuY3Rpb24gaW50ZXJzZWN0c0hvbGVFZGdlKCBpblNoYXBlUHQsIGluSG9sZVB0ICkge1xuXG5cdFx0XHRcdC8vIGNoZWNrcyBmb3IgaW50ZXJzZWN0aW9ucyB3aXRoIGhvbGUgZWRnZXNcblx0XHRcdFx0dmFyIGloSWR4LCBjaGtIb2xlLFxuXHRcdFx0XHRcdGhJZHgsIG5leHRJZHgsIGludGVyc2VjdGlvbjtcblx0XHRcdFx0Zm9yICggaWhJZHggPSAwOyBpaElkeCA8IGluZGVwSG9sZXMubGVuZ3RoOyBpaElkeCArKyApIHtcblxuXHRcdFx0XHRcdGNoa0hvbGUgPSBob2xlc1sgaW5kZXBIb2xlc1sgaWhJZHggXV07XG5cdFx0XHRcdFx0Zm9yICggaElkeCA9IDA7IGhJZHggPCBjaGtIb2xlLmxlbmd0aDsgaElkeCArKyApIHtcblxuXHRcdFx0XHRcdFx0bmV4dElkeCA9IGhJZHggKyAxOyBuZXh0SWR4ICU9IGNoa0hvbGUubGVuZ3RoO1xuXHRcdFx0XHRcdFx0aW50ZXJzZWN0aW9uID0gaW50ZXJzZWN0X3NlZ21lbnRzXzJEKCBpblNoYXBlUHQsIGluSG9sZVB0LCBjaGtIb2xlWyBoSWR4IF0sIGNoa0hvbGVbIG5leHRJZHggXSwgdHJ1ZSApO1xuXHRcdFx0XHRcdFx0aWYgKCBpbnRlcnNlY3Rpb24ubGVuZ3RoID4gMCApXHRcdHJldHVyblx0dHJ1ZTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVyblx0ZmFsc2U7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIGhvbGVJbmRleCwgc2hhcGVJbmRleCxcblx0XHRcdFx0c2hhcGVQdCwgaG9sZVB0LFxuXHRcdFx0XHRob2xlSWR4LCBjdXRLZXksIGZhaWxlZEN1dHMgPSBbXSxcblx0XHRcdFx0dG1wU2hhcGUxLCB0bXBTaGFwZTIsXG5cdFx0XHRcdHRtcEhvbGUxLCB0bXBIb2xlMjtcblxuXHRcdFx0Zm9yICggdmFyIGggPSAwLCBobCA9IGhvbGVzLmxlbmd0aDsgaCA8IGhsOyBoICsrICkge1xuXG5cdFx0XHRcdGluZGVwSG9sZXMucHVzaCggaCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBtaW5TaGFwZUluZGV4ID0gMDtcblx0XHRcdHZhciBjb3VudGVyID0gaW5kZXBIb2xlcy5sZW5ndGggKiAyO1xuXHRcdFx0d2hpbGUgKCBpbmRlcEhvbGVzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdFx0Y291bnRlciAtLTtcblx0XHRcdFx0aWYgKCBjb3VudGVyIDwgMCApIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUubG9nKCBcIkluZmluaXRlIExvb3AhIEhvbGVzIGxlZnQ6XCIgKyBpbmRlcEhvbGVzLmxlbmd0aCArIFwiLCBQcm9iYWJseSBIb2xlIG91dHNpZGUgU2hhcGUhXCIgKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gc2VhcmNoIGZvciBzaGFwZS12ZXJ0ZXggYW5kIGhvbGUtdmVydGV4LFxuXHRcdFx0XHQvLyB3aGljaCBjYW4gYmUgY29ubmVjdGVkIHdpdGhvdXQgaW50ZXJzZWN0aW9uc1xuXHRcdFx0XHRmb3IgKCBzaGFwZUluZGV4ID0gbWluU2hhcGVJbmRleDsgc2hhcGVJbmRleCA8IHNoYXBlLmxlbmd0aDsgc2hhcGVJbmRleCArKyApIHtcblxuXHRcdFx0XHRcdHNoYXBlUHQgPSBzaGFwZVsgc2hhcGVJbmRleCBdO1xuXHRcdFx0XHRcdGhvbGVJbmRleFx0PSAtIDE7XG5cblx0XHRcdFx0XHQvLyBzZWFyY2ggZm9yIGhvbGUgd2hpY2ggY2FuIGJlIHJlYWNoZWQgd2l0aG91dCBpbnRlcnNlY3Rpb25zXG5cdFx0XHRcdFx0Zm9yICggdmFyIGggPSAwOyBoIDwgaW5kZXBIb2xlcy5sZW5ndGg7IGggKysgKSB7XG5cblx0XHRcdFx0XHRcdGhvbGVJZHggPSBpbmRlcEhvbGVzWyBoIF07XG5cblx0XHRcdFx0XHRcdC8vIHByZXZlbnQgbXVsdGlwbGUgY2hlY2tzXG5cdFx0XHRcdFx0XHRjdXRLZXkgPSBzaGFwZVB0LnggKyBcIjpcIiArIHNoYXBlUHQueSArIFwiOlwiICsgaG9sZUlkeDtcblx0XHRcdFx0XHRcdGlmICggZmFpbGVkQ3V0c1sgY3V0S2V5IF0gIT09IHVuZGVmaW5lZCApXHRcdFx0Y29udGludWU7XG5cblx0XHRcdFx0XHRcdGhvbGUgPSBob2xlc1sgaG9sZUlkeCBdO1xuXHRcdFx0XHRcdFx0Zm9yICggdmFyIGgyID0gMDsgaDIgPCBob2xlLmxlbmd0aDsgaDIgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0aG9sZVB0ID0gaG9sZVsgaDIgXTtcblx0XHRcdFx0XHRcdFx0aWYgKCAhIGlzQ3V0TGluZUluc2lkZUFuZ2xlcyggc2hhcGVJbmRleCwgaDIgKSApXHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGludGVyc2VjdHNTaGFwZUVkZ2UoIHNoYXBlUHQsIGhvbGVQdCApIClcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0XHRcdGlmICggaW50ZXJzZWN0c0hvbGVFZGdlKCBzaGFwZVB0LCBob2xlUHQgKSApXHRcdGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0XHRcdGhvbGVJbmRleCA9IGgyO1xuXHRcdFx0XHRcdFx0XHRpbmRlcEhvbGVzLnNwbGljZSggaCwgMSApO1xuXG5cdFx0XHRcdFx0XHRcdHRtcFNoYXBlMSA9IHNoYXBlLnNsaWNlKCAwLCBzaGFwZUluZGV4ICsgMSApO1xuXHRcdFx0XHRcdFx0XHR0bXBTaGFwZTIgPSBzaGFwZS5zbGljZSggc2hhcGVJbmRleCApO1xuXHRcdFx0XHRcdFx0XHR0bXBIb2xlMSA9IGhvbGUuc2xpY2UoIGhvbGVJbmRleCApO1xuXHRcdFx0XHRcdFx0XHR0bXBIb2xlMiA9IGhvbGUuc2xpY2UoIDAsIGhvbGVJbmRleCArIDEgKTtcblxuXHRcdFx0XHRcdFx0XHRzaGFwZSA9IHRtcFNoYXBlMS5jb25jYXQoIHRtcEhvbGUxICkuY29uY2F0KCB0bXBIb2xlMiApLmNvbmNhdCggdG1wU2hhcGUyICk7XG5cblx0XHRcdFx0XHRcdFx0bWluU2hhcGVJbmRleCA9IHNoYXBlSW5kZXg7XG5cblx0XHRcdFx0XHRcdFx0Ly8gRGVidWcgb25seSwgdG8gc2hvdyB0aGUgc2VsZWN0ZWQgY3V0c1xuXHRcdFx0XHRcdFx0XHQvLyBnbG9iX0N1dExpbmVzLnB1c2goIFsgc2hhcGVQdCwgaG9sZVB0IF0gKTtcblxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBob2xlSW5kZXggPj0gMCApXHRicmVhaztcdFx0Ly8gaG9sZS12ZXJ0ZXggZm91bmRcblxuXHRcdFx0XHRcdFx0ZmFpbGVkQ3V0c1sgY3V0S2V5IF0gPSB0cnVlO1x0XHRcdC8vIHJlbWVtYmVyIGZhaWx1cmVcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIGhvbGVJbmRleCA+PSAwIClcdGJyZWFrO1x0XHQvLyBob2xlLXZlcnRleCBmb3VuZFxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2hhcGU7IFx0XHRcdC8qIHNoYXBlIHdpdGggbm8gaG9sZXMgKi9cblxuXHRcdH1cblxuXG5cdFx0dmFyIGksIGlsLCBmLCBmYWNlLFxuXHRcdFx0a2V5LCBpbmRleCxcblx0XHRcdGFsbFBvaW50c01hcCA9IHt9O1xuXG5cdFx0Ly8gVG8gbWFpbnRhaW4gcmVmZXJlbmNlIHRvIG9sZCBzaGFwZSwgb25lIG11c3QgbWF0Y2ggY29vcmRpbmF0ZXMsIG9yIG9mZnNldCB0aGUgaW5kaWNlcyBmcm9tIG9yaWdpbmFsIGFycmF5cy4gSXQncyBwcm9iYWJseSBlYXNpZXIgdG8gZG8gdGhlIGZpcnN0LlxuXG5cdFx0dmFyIGFsbHBvaW50cyA9IGNvbnRvdXIuY29uY2F0KCk7XG5cblx0XHRmb3IgKCB2YXIgaCA9IDAsIGhsID0gaG9sZXMubGVuZ3RoOyBoIDwgaGw7IGggKysgKSB7XG5cblx0XHRcdEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KCBhbGxwb2ludHMsIGhvbGVzWyBoIF0gKTtcblxuXHRcdH1cblxuXHRcdC8vY29uc29sZS5sb2coIFwiYWxscG9pbnRzXCIsYWxscG9pbnRzLCBhbGxwb2ludHMubGVuZ3RoICk7XG5cblx0XHQvLyBwcmVwYXJlIGFsbCBwb2ludHMgbWFwXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBhbGxwb2ludHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdGtleSA9IGFsbHBvaW50c1sgaSBdLnggKyBcIjpcIiArIGFsbHBvaW50c1sgaSBdLnk7XG5cblx0XHRcdGlmICggYWxsUG9pbnRzTWFwWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggXCJUSFJFRS5TaGFwZVV0aWxzOiBEdXBsaWNhdGUgcG9pbnRcIiwga2V5LCBpICk7XG5cblx0XHRcdH1cblxuXHRcdFx0YWxsUG9pbnRzTWFwWyBrZXkgXSA9IGk7XG5cblx0XHR9XG5cblx0XHQvLyByZW1vdmUgaG9sZXMgYnkgY3V0dGluZyBwYXRocyB0byBob2xlcyBhbmQgYWRkaW5nIHRoZW0gdG8gdGhlIHNoYXBlXG5cdFx0dmFyIHNoYXBlV2l0aG91dEhvbGVzID0gcmVtb3ZlSG9sZXMoIGNvbnRvdXIsIGhvbGVzICk7XG5cblx0XHR2YXIgdHJpYW5nbGVzID0gU2hhcGVVdGlscy50cmlhbmd1bGF0ZSggc2hhcGVXaXRob3V0SG9sZXMsIGZhbHNlICk7IC8vIFRydWUgcmV0dXJucyBpbmRpY2VzIGZvciBwb2ludHMgb2Ygc3Bvb2xlZCBzaGFwZVxuXHRcdC8vY29uc29sZS5sb2coIFwidHJpYW5nbGVzXCIsdHJpYW5nbGVzLCB0cmlhbmdsZXMubGVuZ3RoICk7XG5cblx0XHQvLyBjaGVjayBhbGwgZmFjZSB2ZXJ0aWNlcyBhZ2FpbnN0IGFsbCBwb2ludHMgbWFwXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSB0cmlhbmdsZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdGZhY2UgPSB0cmlhbmdsZXNbIGkgXTtcblxuXHRcdFx0Zm9yICggZiA9IDA7IGYgPCAzOyBmICsrICkge1xuXG5cdFx0XHRcdGtleSA9IGZhY2VbIGYgXS54ICsgXCI6XCIgKyBmYWNlWyBmIF0ueTtcblxuXHRcdFx0XHRpbmRleCA9IGFsbFBvaW50c01hcFsga2V5IF07XG5cblx0XHRcdFx0aWYgKCBpbmRleCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0ZmFjZVsgZiBdID0gaW5kZXg7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdHJpYW5nbGVzLmNvbmNhdCgpO1xuXG5cdH0sXG5cblx0aXNDbG9ja1dpc2U6IGZ1bmN0aW9uICggcHRzICkge1xuXG5cdFx0cmV0dXJuIFNoYXBlVXRpbHMuYXJlYSggcHRzICkgPCAwO1xuXG5cdH1cblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwOi8vd3d3LmxhYjRnYW1lcy5uZXQveno4NS9ibG9nXG4gKlxuICogQ3JlYXRlcyBleHRydWRlZCBnZW9tZXRyeSBmcm9tIGEgcGF0aCBzaGFwZS5cbiAqXG4gKiBwYXJhbWV0ZXJzID0ge1xuICpcbiAqICBjdXJ2ZVNlZ21lbnRzOiA8aW50PiwgLy8gbnVtYmVyIG9mIHBvaW50cyBvbiB0aGUgY3VydmVzXG4gKiAgc3RlcHM6IDxpbnQ+LCAvLyBudW1iZXIgb2YgcG9pbnRzIGZvciB6LXNpZGUgZXh0cnVzaW9ucyAvIHVzZWQgZm9yIHN1YmRpdmlkaW5nIHNlZ21lbnRzIG9mIGV4dHJ1ZGUgc3BsaW5lIHRvb1xuICogIGFtb3VudDogPGludD4sIC8vIERlcHRoIHRvIGV4dHJ1ZGUgdGhlIHNoYXBlXG4gKlxuICogIGJldmVsRW5hYmxlZDogPGJvb2w+LCAvLyB0dXJuIG9uIGJldmVsXG4gKiAgYmV2ZWxUaGlja25lc3M6IDxmbG9hdD4sIC8vIGhvdyBkZWVwIGludG8gdGhlIG9yaWdpbmFsIHNoYXBlIGJldmVsIGdvZXNcbiAqICBiZXZlbFNpemU6IDxmbG9hdD4sIC8vIGhvdyBmYXIgZnJvbSBzaGFwZSBvdXRsaW5lIGlzIGJldmVsXG4gKiAgYmV2ZWxTZWdtZW50czogPGludD4sIC8vIG51bWJlciBvZiBiZXZlbCBsYXllcnNcbiAqXG4gKiAgZXh0cnVkZVBhdGg6IDxUSFJFRS5DdXJ2ZT4gLy8gY3VydmUgdG8gZXh0cnVkZSBzaGFwZSBhbG9uZ1xuICogIGZyYW1lczogPE9iamVjdD4gLy8gY29udGFpbmluZyBhcnJheXMgb2YgdGFuZ2VudHMsIG5vcm1hbHMsIGJpbm9ybWFsc1xuICpcbiAqICBVVkdlbmVyYXRvcjogPE9iamVjdD4gLy8gb2JqZWN0IHRoYXQgcHJvdmlkZXMgVVYgZ2VuZXJhdG9yIGZ1bmN0aW9uc1xuICpcbiAqIH1cbiAqL1xuXG4vLyBFeHRydWRlR2VvbWV0cnlcblxuZnVuY3Rpb24gRXh0cnVkZUdlb21ldHJ5KCBzaGFwZXMsIG9wdGlvbnMgKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdFeHRydWRlR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRzaGFwZXM6IHNoYXBlcyxcblx0XHRvcHRpb25zOiBvcHRpb25zXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBFeHRydWRlQnVmZmVyR2VvbWV0cnkoIHNoYXBlcywgb3B0aW9ucyApICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cbkV4dHJ1ZGVHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcbkV4dHJ1ZGVHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBFeHRydWRlR2VvbWV0cnk7XG5cbi8vIEV4dHJ1ZGVCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBFeHRydWRlQnVmZmVyR2VvbWV0cnkoIHNoYXBlcywgb3B0aW9ucyApIHtcblxuXHRpZiAoIHR5cGVvZiAoIHNoYXBlcyApID09PSBcInVuZGVmaW5lZFwiICkge1xuXG5cdFx0c2hhcGVzID0gW107XG5cdFx0cmV0dXJuO1xuXG5cdH1cblxuXHRCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0V4dHJ1ZGVCdWZmZXJHZW9tZXRyeSc7XG5cblx0c2hhcGVzID0gQXJyYXkuaXNBcnJheSggc2hhcGVzICkgPyBzaGFwZXMgOiBbIHNoYXBlcyBdO1xuXG5cdHRoaXMuYWRkU2hhcGVMaXN0KCBzaGFwZXMsIG9wdGlvbnMgKTtcblxuXHR0aGlzLmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCk7XG5cblx0Ly8gY2FuJ3QgcmVhbGx5IHVzZSBhdXRvbWF0aWMgdmVydGV4IG5vcm1hbHNcblx0Ly8gYXMgdGhlbiBmcm9udCBhbmQgYmFjayBzaWRlcyBnZXQgc21vb3RoZWQgdG9vXG5cdC8vIHNob3VsZCBkbyBzZXBhcmF0ZSBzbW9vdGhpbmcganVzdCBmb3Igc2lkZXNcblxuXHQvL3RoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtcblxuXHQvL2NvbnNvbGUubG9nKCBcInRvb2tcIiwgKCBEYXRlLm5vdygpIC0gc3RhcnRUaW1lICkgKTtcblxufVxuXG5FeHRydWRlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5FeHRydWRlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gRXh0cnVkZUJ1ZmZlckdlb21ldHJ5O1xuXG5FeHRydWRlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmdldEFycmF5cyA9IGZ1bmN0aW9uICgpIHtcblxuXHR2YXIgcG9zaXRpb25BdHRyaWJ1dGUgPSB0aGlzLmdldEF0dHJpYnV0ZSggXCJwb3NpdGlvblwiICk7XG5cdHZhciB2ZXJ0aWNlc0FycmF5ID0gcG9zaXRpb25BdHRyaWJ1dGUgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggcG9zaXRpb25BdHRyaWJ1dGUuYXJyYXkgKSA6IFtdO1xuXG5cdHZhciB1dkF0dHJpYnV0ZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCBcInV2XCIgKTtcblx0dmFyIHV2QXJyYXkgPSB1dkF0dHJpYnV0ZSA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCB1dkF0dHJpYnV0ZS5hcnJheSApIDogW107XG5cblx0dmFyIEluZGV4QXR0cmlidXRlID0gdGhpcy5pbmRleDtcblx0dmFyIGluZGljZXNBcnJheSA9IEluZGV4QXR0cmlidXRlID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoIEluZGV4QXR0cmlidXRlLmFycmF5ICkgOiBbXTtcblxuXHRyZXR1cm4ge1xuXHRcdHBvc2l0aW9uOiB2ZXJ0aWNlc0FycmF5LFxuXHRcdHV2OiB1dkFycmF5LFxuXHRcdGluZGV4OiBpbmRpY2VzQXJyYXlcblx0fTtcblxufTtcblxuRXh0cnVkZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5hZGRTaGFwZUxpc3QgPSBmdW5jdGlvbiAoIHNoYXBlcywgb3B0aW9ucyApIHtcblxuXHR2YXIgc2wgPSBzaGFwZXMubGVuZ3RoO1xuXHRvcHRpb25zLmFycmF5cyA9IHRoaXMuZ2V0QXJyYXlzKCk7XG5cblx0Zm9yICggdmFyIHMgPSAwOyBzIDwgc2w7IHMgKysgKSB7XG5cblx0XHR2YXIgc2hhcGUgPSBzaGFwZXNbIHMgXTtcblx0XHR0aGlzLmFkZFNoYXBlKCBzaGFwZSwgb3B0aW9ucyApO1xuXG5cdH1cblxuXHR0aGlzLnNldEluZGV4KCBvcHRpb25zLmFycmF5cy5pbmRleCApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG9wdGlvbnMuYXJyYXlzLnBvc2l0aW9uLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICd1dicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBvcHRpb25zLmFycmF5cy51diwgMiApICk7XG5cbn07XG5cbkV4dHJ1ZGVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuYWRkU2hhcGUgPSBmdW5jdGlvbiAoIHNoYXBlLCBvcHRpb25zICkge1xuXG5cdHZhciBhcnJheXMgPSBvcHRpb25zLmFycmF5cyA/IG9wdGlvbnMuYXJyYXlzIDogdGhpcy5nZXRBcnJheXMoKTtcblx0dmFyIHZlcnRpY2VzQXJyYXkgPSBhcnJheXMucG9zaXRpb247XG5cdHZhciBpbmRpY2VzQXJyYXkgPSBhcnJheXMuaW5kZXg7XG5cdHZhciB1dkFycmF5ID0gYXJyYXlzLnV2O1xuXG5cdHZhciBwbGFjZWhvbGRlciA9IFtdO1xuXG5cblx0dmFyIGFtb3VudCA9IG9wdGlvbnMuYW1vdW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFtb3VudCA6IDEwMDtcblxuXHR2YXIgYmV2ZWxUaGlja25lc3MgPSBvcHRpb25zLmJldmVsVGhpY2tuZXNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmJldmVsVGhpY2tuZXNzIDogNjsgLy8gMTBcblx0dmFyIGJldmVsU2l6ZSA9IG9wdGlvbnMuYmV2ZWxTaXplICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmJldmVsU2l6ZSA6IGJldmVsVGhpY2tuZXNzIC0gMjsgLy8gOFxuXHR2YXIgYmV2ZWxTZWdtZW50cyA9IG9wdGlvbnMuYmV2ZWxTZWdtZW50cyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5iZXZlbFNlZ21lbnRzIDogMztcblxuXHR2YXIgYmV2ZWxFbmFibGVkID0gb3B0aW9ucy5iZXZlbEVuYWJsZWQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYmV2ZWxFbmFibGVkIDogdHJ1ZTsgLy8gZmFsc2VcblxuXHR2YXIgY3VydmVTZWdtZW50cyA9IG9wdGlvbnMuY3VydmVTZWdtZW50cyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jdXJ2ZVNlZ21lbnRzIDogMTI7XG5cblx0dmFyIHN0ZXBzID0gb3B0aW9ucy5zdGVwcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zdGVwcyA6IDE7XG5cblx0dmFyIGV4dHJ1ZGVQYXRoID0gb3B0aW9ucy5leHRydWRlUGF0aDtcblx0dmFyIGV4dHJ1ZGVQdHMsIGV4dHJ1ZGVCeVBhdGggPSBmYWxzZTtcblxuXHQvLyBVc2UgZGVmYXVsdCBXb3JsZFVWR2VuZXJhdG9yIGlmIG5vIFVWIGdlbmVyYXRvcnMgYXJlIHNwZWNpZmllZC5cblx0dmFyIHV2Z2VuID0gb3B0aW9ucy5VVkdlbmVyYXRvciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5VVkdlbmVyYXRvciA6IEV4dHJ1ZGVHZW9tZXRyeS5Xb3JsZFVWR2VuZXJhdG9yO1xuXG5cdHZhciBzcGxpbmVUdWJlLCBiaW5vcm1hbCwgbm9ybWFsLCBwb3NpdGlvbjI7XG5cdGlmICggZXh0cnVkZVBhdGggKSB7XG5cblx0XHRleHRydWRlUHRzID0gZXh0cnVkZVBhdGguZ2V0U3BhY2VkUG9pbnRzKCBzdGVwcyApO1xuXG5cdFx0ZXh0cnVkZUJ5UGF0aCA9IHRydWU7XG5cdFx0YmV2ZWxFbmFibGVkID0gZmFsc2U7IC8vIGJldmVscyBub3Qgc3VwcG9ydGVkIGZvciBwYXRoIGV4dHJ1c2lvblxuXG5cdFx0Ly8gU0VUVVAgVE5CIHZhcmlhYmxlc1xuXG5cdFx0Ly8gVE9ETzEgLSBoYXZlIGEgLmlzQ2xvc2VkIGluIHNwbGluZT9cblxuXHRcdHNwbGluZVR1YmUgPSBvcHRpb25zLmZyYW1lcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5mcmFtZXMgOiBleHRydWRlUGF0aC5jb21wdXRlRnJlbmV0RnJhbWVzKCBzdGVwcywgZmFsc2UgKTtcblxuXHRcdC8vIGNvbnNvbGUubG9nKHNwbGluZVR1YmUsICdzcGxpbmVUdWJlJywgc3BsaW5lVHViZS5ub3JtYWxzLmxlbmd0aCwgJ3N0ZXBzJywgc3RlcHMsICdleHRydWRlUHRzJywgZXh0cnVkZVB0cy5sZW5ndGgpO1xuXG5cdFx0Ymlub3JtYWwgPSBuZXcgVmVjdG9yMygpO1xuXHRcdG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0cG9zaXRpb24yID0gbmV3IFZlY3RvcjMoKTtcblxuXHR9XG5cblx0Ly8gU2FmZWd1YXJkcyBpZiBiZXZlbHMgYXJlIG5vdCBlbmFibGVkXG5cblx0aWYgKCAhIGJldmVsRW5hYmxlZCApIHtcblxuXHRcdGJldmVsU2VnbWVudHMgPSAwO1xuXHRcdGJldmVsVGhpY2tuZXNzID0gMDtcblx0XHRiZXZlbFNpemUgPSAwO1xuXG5cdH1cblxuXHQvLyBWYXJpYWJsZXMgaW5pdGlhbGl6YXRpb25cblxuXHR2YXIgYWhvbGUsIGgsIGhsOyAvLyBsb29waW5nIG9mIGhvbGVzXG5cdHZhciBzY29wZSA9IHRoaXM7XG5cblx0dmFyIHNoYXBlUG9pbnRzID0gc2hhcGUuZXh0cmFjdFBvaW50cyggY3VydmVTZWdtZW50cyApO1xuXG5cdHZhciB2ZXJ0aWNlcyA9IHNoYXBlUG9pbnRzLnNoYXBlO1xuXHR2YXIgaG9sZXMgPSBzaGFwZVBvaW50cy5ob2xlcztcblxuXHR2YXIgcmV2ZXJzZSA9ICEgU2hhcGVVdGlscy5pc0Nsb2NrV2lzZSggdmVydGljZXMgKTtcblxuXHRpZiAoIHJldmVyc2UgKSB7XG5cblx0XHR2ZXJ0aWNlcyA9IHZlcnRpY2VzLnJldmVyc2UoKTtcblxuXHRcdC8vIE1heWJlIHdlIHNob3VsZCBhbHNvIGNoZWNrIGlmIGhvbGVzIGFyZSBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uLCBqdXN0IHRvIGJlIHNhZmUgLi4uXG5cblx0XHRmb3IgKCBoID0gMCwgaGwgPSBob2xlcy5sZW5ndGg7IGggPCBobDsgaCArKyApIHtcblxuXHRcdFx0YWhvbGUgPSBob2xlc1sgaCBdO1xuXG5cdFx0XHRpZiAoIFNoYXBlVXRpbHMuaXNDbG9ja1dpc2UoIGFob2xlICkgKSB7XG5cblx0XHRcdFx0aG9sZXNbIGggXSA9IGFob2xlLnJldmVyc2UoKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV2ZXJzZSA9IGZhbHNlOyAvLyBJZiB2ZXJ0aWNlcyBhcmUgaW4gb3JkZXIgbm93LCB3ZSBzaG91bGRuJ3QgbmVlZCB0byB3b3JyeSBhYm91dCB0aGVtIGFnYWluIChob3BlZnVsbHkpIVxuXG5cdH1cblxuXG5cdHZhciBmYWNlcyA9IFNoYXBlVXRpbHMudHJpYW5ndWxhdGVTaGFwZSggdmVydGljZXMsIGhvbGVzICk7XG5cblx0LyogVmVydGljZXMgKi9cblxuXHR2YXIgY29udG91ciA9IHZlcnRpY2VzOyAvLyB2ZXJ0aWNlcyBoYXMgYWxsIHBvaW50cyBidXQgY29udG91ciBoYXMgb25seSBwb2ludHMgb2YgY2lyY3VtZmVyZW5jZVxuXG5cdGZvciAoIGggPSAwLCBobCA9IGhvbGVzLmxlbmd0aDsgaCA8IGhsOyBoICsrICkge1xuXG5cdFx0YWhvbGUgPSBob2xlc1sgaCBdO1xuXG5cdFx0dmVydGljZXMgPSB2ZXJ0aWNlcy5jb25jYXQoIGFob2xlICk7XG5cblx0fVxuXG5cblx0ZnVuY3Rpb24gc2NhbGVQdDIoIHB0LCB2ZWMsIHNpemUgKSB7XG5cblx0XHRpZiAoICEgdmVjICkgY29uc29sZS5lcnJvciggXCJUSFJFRS5FeHRydWRlR2VvbWV0cnk6IHZlYyBkb2VzIG5vdCBleGlzdFwiICk7XG5cblx0XHRyZXR1cm4gdmVjLmNsb25lKCkubXVsdGlwbHlTY2FsYXIoIHNpemUgKS5hZGQoIHB0ICk7XG5cblx0fVxuXG5cdHZhciBiLCBicywgdCwgeixcblx0XHR2ZXJ0LCB2bGVuID0gdmVydGljZXMubGVuZ3RoLFxuXHRcdGZhY2UsIGZsZW4gPSBmYWNlcy5sZW5ndGg7XG5cblxuXHQvLyBGaW5kIGRpcmVjdGlvbnMgZm9yIHBvaW50IG1vdmVtZW50XG5cblxuXHRmdW5jdGlvbiBnZXRCZXZlbFZlYyggaW5QdCwgaW5QcmV2LCBpbk5leHQgKSB7XG5cblx0XHQvLyBjb21wdXRlcyBmb3IgaW5QdCB0aGUgY29ycmVzcG9uZGluZyBwb2ludCBpblB0JyBvbiBhIG5ldyBjb250b3VyXG5cdFx0Ly8gICBzaGlmdGVkIGJ5IDEgdW5pdCAobGVuZ3RoIG9mIG5vcm1hbGl6ZWQgdmVjdG9yKSB0byB0aGUgbGVmdFxuXHRcdC8vIGlmIHdlIHdhbGsgYWxvbmcgY29udG91ciBjbG9ja3dpc2UsIHRoaXMgbmV3IGNvbnRvdXIgaXMgb3V0c2lkZSB0aGUgb2xkIG9uZVxuXHRcdC8vXG5cdFx0Ly8gaW5QdCcgaXMgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIGxpbmVzIHBhcmFsbGVsIHRvIHRoZSB0d29cblx0XHQvLyAgYWRqYWNlbnQgZWRnZXMgb2YgaW5QdCBhdCBhIGRpc3RhbmNlIG9mIDEgdW5pdCBvbiB0aGUgbGVmdCBzaWRlLlxuXG5cdFx0dmFyIHZfdHJhbnNfeCwgdl90cmFuc195LCBzaHJpbmtfYnkgPSAxOyAvLyByZXN1bHRpbmcgdHJhbnNsYXRpb24gdmVjdG9yIGZvciBpblB0XG5cblx0XHQvLyBnb29kIHJlYWRpbmcgZm9yIGdlb21ldHJ5IGFsZ29yaXRobXMgKGhlcmU6IGxpbmUtbGluZSBpbnRlcnNlY3Rpb24pXG5cdFx0Ly8gaHR0cDovL2dlb21hbGdvcml0aG1zLmNvbS9hMDUtX2ludGVyc2VjdC0xLmh0bWxcblxuXHRcdHZhciB2X3ByZXZfeCA9IGluUHQueCAtIGluUHJldi54LFxuXHRcdFx0dl9wcmV2X3kgPSBpblB0LnkgLSBpblByZXYueTtcblx0XHR2YXIgdl9uZXh0X3ggPSBpbk5leHQueCAtIGluUHQueCxcblx0XHRcdHZfbmV4dF95ID0gaW5OZXh0LnkgLSBpblB0Lnk7XG5cblx0XHR2YXIgdl9wcmV2X2xlbnNxID0gKCB2X3ByZXZfeCAqIHZfcHJldl94ICsgdl9wcmV2X3kgKiB2X3ByZXZfeSApO1xuXG5cdFx0Ly8gY2hlY2sgZm9yIGNvbGxpbmVhciBlZGdlc1xuXHRcdHZhciBjb2xsaW5lYXIwID0gKCB2X3ByZXZfeCAqIHZfbmV4dF95IC0gdl9wcmV2X3kgKiB2X25leHRfeCApO1xuXG5cdFx0aWYgKCBNYXRoLmFicyggY29sbGluZWFyMCApID4gTnVtYmVyLkVQU0lMT04gKSB7XG5cblx0XHRcdC8vIG5vdCBjb2xsaW5lYXJcblxuXHRcdFx0Ly8gbGVuZ3RoIG9mIHZlY3RvcnMgZm9yIG5vcm1hbGl6aW5nXG5cblx0XHRcdHZhciB2X3ByZXZfbGVuID0gTWF0aC5zcXJ0KCB2X3ByZXZfbGVuc3EgKTtcblx0XHRcdHZhciB2X25leHRfbGVuID0gTWF0aC5zcXJ0KCB2X25leHRfeCAqIHZfbmV4dF94ICsgdl9uZXh0X3kgKiB2X25leHRfeSApO1xuXG5cdFx0XHQvLyBzaGlmdCBhZGphY2VudCBwb2ludHMgYnkgdW5pdCB2ZWN0b3JzIHRvIHRoZSBsZWZ0XG5cblx0XHRcdHZhciBwdFByZXZTaGlmdF94ID0gKCBpblByZXYueCAtIHZfcHJldl95IC8gdl9wcmV2X2xlbiApO1xuXHRcdFx0dmFyIHB0UHJldlNoaWZ0X3kgPSAoIGluUHJldi55ICsgdl9wcmV2X3ggLyB2X3ByZXZfbGVuICk7XG5cblx0XHRcdHZhciBwdE5leHRTaGlmdF94ID0gKCBpbk5leHQueCAtIHZfbmV4dF95IC8gdl9uZXh0X2xlbiApO1xuXHRcdFx0dmFyIHB0TmV4dFNoaWZ0X3kgPSAoIGluTmV4dC55ICsgdl9uZXh0X3ggLyB2X25leHRfbGVuICk7XG5cblx0XHRcdC8vIHNjYWxpbmcgZmFjdG9yIGZvciB2X3ByZXYgdG8gaW50ZXJzZWN0aW9uIHBvaW50XG5cblx0XHRcdHZhciBzZiA9ICggKCBwdE5leHRTaGlmdF94IC0gcHRQcmV2U2hpZnRfeCApICogdl9uZXh0X3kgLVxuXHRcdFx0XHRcdCggcHROZXh0U2hpZnRfeSAtIHB0UHJldlNoaWZ0X3kgKSAqIHZfbmV4dF94ICkgL1xuXHRcdFx0XHQoIHZfcHJldl94ICogdl9uZXh0X3kgLSB2X3ByZXZfeSAqIHZfbmV4dF94ICk7XG5cblx0XHRcdC8vIHZlY3RvciBmcm9tIGluUHQgdG8gaW50ZXJzZWN0aW9uIHBvaW50XG5cblx0XHRcdHZfdHJhbnNfeCA9ICggcHRQcmV2U2hpZnRfeCArIHZfcHJldl94ICogc2YgLSBpblB0LnggKTtcblx0XHRcdHZfdHJhbnNfeSA9ICggcHRQcmV2U2hpZnRfeSArIHZfcHJldl95ICogc2YgLSBpblB0LnkgKTtcblxuXHRcdFx0Ly8gRG9uJ3Qgbm9ybWFsaXplISwgb3RoZXJ3aXNlIHNoYXJwIGNvcm5lcnMgYmVjb21lIHVnbHlcblx0XHRcdC8vICBidXQgcHJldmVudCBjcmF6eSBzcGlrZXNcblx0XHRcdHZhciB2X3RyYW5zX2xlbnNxID0gKCB2X3RyYW5zX3ggKiB2X3RyYW5zX3ggKyB2X3RyYW5zX3kgKiB2X3RyYW5zX3kgKTtcblx0XHRcdGlmICggdl90cmFuc19sZW5zcSA8PSAyICkge1xuXG5cdFx0XHRcdHJldHVybiBuZXcgVmVjdG9yMiggdl90cmFuc194LCB2X3RyYW5zX3kgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRzaHJpbmtfYnkgPSBNYXRoLnNxcnQoIHZfdHJhbnNfbGVuc3EgLyAyICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIGhhbmRsZSBzcGVjaWFsIGNhc2Ugb2YgY29sbGluZWFyIGVkZ2VzXG5cblx0XHRcdHZhciBkaXJlY3Rpb25fZXEgPSBmYWxzZTsgLy8gYXNzdW1lczogb3Bwb3NpdGVcblx0XHRcdGlmICggdl9wcmV2X3ggPiBOdW1iZXIuRVBTSUxPTiApIHtcblxuXHRcdFx0XHRpZiAoIHZfbmV4dF94ID4gTnVtYmVyLkVQU0lMT04gKSB7XG5cblx0XHRcdFx0XHRkaXJlY3Rpb25fZXEgPSB0cnVlO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRpZiAoIHZfcHJldl94IDwgLSBOdW1iZXIuRVBTSUxPTiApIHtcblxuXHRcdFx0XHRcdGlmICggdl9uZXh0X3ggPCAtIE51bWJlci5FUFNJTE9OICkge1xuXG5cdFx0XHRcdFx0XHRkaXJlY3Rpb25fZXEgPSB0cnVlO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRpZiAoIE1hdGguc2lnbiggdl9wcmV2X3kgKSA9PT0gTWF0aC5zaWduKCB2X25leHRfeSApICkge1xuXG5cdFx0XHRcdFx0XHRkaXJlY3Rpb25fZXEgPSB0cnVlO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGRpcmVjdGlvbl9lcSApIHtcblxuXHRcdFx0XHQvLyBjb25zb2xlLmxvZyhcIldhcm5pbmc6IGxpbmVzIGFyZSBhIHN0cmFpZ2h0IHNlcXVlbmNlXCIpO1xuXHRcdFx0XHR2X3RyYW5zX3ggPSAtIHZfcHJldl95O1xuXHRcdFx0XHR2X3RyYW5zX3kgPSB2X3ByZXZfeDtcblx0XHRcdFx0c2hyaW5rX2J5ID0gTWF0aC5zcXJ0KCB2X3ByZXZfbGVuc3EgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBjb25zb2xlLmxvZyhcIldhcm5pbmc6IGxpbmVzIGFyZSBhIHN0cmFpZ2h0IHNwaWtlXCIpO1xuXHRcdFx0XHR2X3RyYW5zX3ggPSB2X3ByZXZfeDtcblx0XHRcdFx0dl90cmFuc195ID0gdl9wcmV2X3k7XG5cdFx0XHRcdHNocmlua19ieSA9IE1hdGguc3FydCggdl9wcmV2X2xlbnNxIC8gMiApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gbmV3IFZlY3RvcjIoIHZfdHJhbnNfeCAvIHNocmlua19ieSwgdl90cmFuc195IC8gc2hyaW5rX2J5ICk7XG5cblx0fVxuXG5cblx0dmFyIGNvbnRvdXJNb3ZlbWVudHMgPSBbXTtcblxuXHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gY29udG91ci5sZW5ndGgsIGogPSBpbCAtIDEsIGsgPSBpICsgMTsgaSA8IGlsOyBpICsrLCBqICsrLCBrICsrICkge1xuXG5cdFx0aWYgKCBqID09PSBpbCApIGogPSAwO1xuXHRcdGlmICggayA9PT0gaWwgKSBrID0gMDtcblxuXHRcdC8vICAoaiktLS0oaSktLS0oaylcblx0XHQvLyBjb25zb2xlLmxvZygnaSxqLGsnLCBpLCBqICwgaylcblxuXHRcdGNvbnRvdXJNb3ZlbWVudHNbIGkgXSA9IGdldEJldmVsVmVjKCBjb250b3VyWyBpIF0sIGNvbnRvdXJbIGogXSwgY29udG91clsgayBdICk7XG5cblx0fVxuXG5cdHZhciBob2xlc01vdmVtZW50cyA9IFtdLFxuXHRcdG9uZUhvbGVNb3ZlbWVudHMsIHZlcnRpY2VzTW92ZW1lbnRzID0gY29udG91ck1vdmVtZW50cy5jb25jYXQoKTtcblxuXHRmb3IgKCBoID0gMCwgaGwgPSBob2xlcy5sZW5ndGg7IGggPCBobDsgaCArKyApIHtcblxuXHRcdGFob2xlID0gaG9sZXNbIGggXTtcblxuXHRcdG9uZUhvbGVNb3ZlbWVudHMgPSBbXTtcblxuXHRcdGZvciAoIGkgPSAwLCBpbCA9IGFob2xlLmxlbmd0aCwgaiA9IGlsIC0gMSwgayA9IGkgKyAxOyBpIDwgaWw7IGkgKyssIGogKyssIGsgKysgKSB7XG5cblx0XHRcdGlmICggaiA9PT0gaWwgKSBqID0gMDtcblx0XHRcdGlmICggayA9PT0gaWwgKSBrID0gMDtcblxuXHRcdFx0Ly8gIChqKS0tLShpKS0tLShrKVxuXHRcdFx0b25lSG9sZU1vdmVtZW50c1sgaSBdID0gZ2V0QmV2ZWxWZWMoIGFob2xlWyBpIF0sIGFob2xlWyBqIF0sIGFob2xlWyBrIF0gKTtcblxuXHRcdH1cblxuXHRcdGhvbGVzTW92ZW1lbnRzLnB1c2goIG9uZUhvbGVNb3ZlbWVudHMgKTtcblx0XHR2ZXJ0aWNlc01vdmVtZW50cyA9IHZlcnRpY2VzTW92ZW1lbnRzLmNvbmNhdCggb25lSG9sZU1vdmVtZW50cyApO1xuXG5cdH1cblxuXG5cdC8vIExvb3AgYmV2ZWxTZWdtZW50cywgMSBmb3IgdGhlIGZyb250LCAxIGZvciB0aGUgYmFja1xuXG5cdGZvciAoIGIgPSAwOyBiIDwgYmV2ZWxTZWdtZW50czsgYiArKyApIHtcblxuXHRcdC8vZm9yICggYiA9IGJldmVsU2VnbWVudHM7IGIgPiAwOyBiIC0tICkge1xuXG5cdFx0dCA9IGIgLyBiZXZlbFNlZ21lbnRzO1xuXHRcdHogPSBiZXZlbFRoaWNrbmVzcyAqIE1hdGguY29zKCB0ICogTWF0aC5QSSAvIDIgKTtcblx0XHRicyA9IGJldmVsU2l6ZSAqIE1hdGguc2luKCB0ICogTWF0aC5QSSAvIDIgKTtcblxuXHRcdC8vIGNvbnRyYWN0IHNoYXBlXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBjb250b3VyLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2ZXJ0ID0gc2NhbGVQdDIoIGNvbnRvdXJbIGkgXSwgY29udG91ck1vdmVtZW50c1sgaSBdLCBicyApO1xuXG5cdFx0XHR2KCB2ZXJ0LngsIHZlcnQueSwgLSB6ICk7XG5cblx0XHR9XG5cblx0XHQvLyBleHBhbmQgaG9sZXNcblxuXHRcdGZvciAoIGggPSAwLCBobCA9IGhvbGVzLmxlbmd0aDsgaCA8IGhsOyBoICsrICkge1xuXG5cdFx0XHRhaG9sZSA9IGhvbGVzWyBoIF07XG5cdFx0XHRvbmVIb2xlTW92ZW1lbnRzID0gaG9sZXNNb3ZlbWVudHNbIGggXTtcblxuXHRcdFx0Zm9yICggaSA9IDAsIGlsID0gYWhvbGUubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdFx0dmVydCA9IHNjYWxlUHQyKCBhaG9sZVsgaSBdLCBvbmVIb2xlTW92ZW1lbnRzWyBpIF0sIGJzICk7XG5cblx0XHRcdFx0diggdmVydC54LCB2ZXJ0LnksIC0geiApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fVxuXG5cdGJzID0gYmV2ZWxTaXplO1xuXG5cdC8vIEJhY2sgZmFjaW5nIHZlcnRpY2VzXG5cblx0Zm9yICggaSA9IDA7IGkgPCB2bGVuOyBpICsrICkge1xuXG5cdFx0dmVydCA9IGJldmVsRW5hYmxlZCA/IHNjYWxlUHQyKCB2ZXJ0aWNlc1sgaSBdLCB2ZXJ0aWNlc01vdmVtZW50c1sgaSBdLCBicyApIDogdmVydGljZXNbIGkgXTtcblxuXHRcdGlmICggISBleHRydWRlQnlQYXRoICkge1xuXG5cdFx0XHR2KCB2ZXJ0LngsIHZlcnQueSwgMCApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gdiggdmVydC54LCB2ZXJ0LnkgKyBleHRydWRlUHRzWyAwIF0ueSwgZXh0cnVkZVB0c1sgMCBdLnggKTtcblxuXHRcdFx0bm9ybWFsLmNvcHkoIHNwbGluZVR1YmUubm9ybWFsc1sgMCBdICkubXVsdGlwbHlTY2FsYXIoIHZlcnQueCApO1xuXHRcdFx0Ymlub3JtYWwuY29weSggc3BsaW5lVHViZS5iaW5vcm1hbHNbIDAgXSApLm11bHRpcGx5U2NhbGFyKCB2ZXJ0LnkgKTtcblxuXHRcdFx0cG9zaXRpb24yLmNvcHkoIGV4dHJ1ZGVQdHNbIDAgXSApLmFkZCggbm9ybWFsICkuYWRkKCBiaW5vcm1hbCApO1xuXG5cdFx0XHR2KCBwb3NpdGlvbjIueCwgcG9zaXRpb24yLnksIHBvc2l0aW9uMi56ICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIEFkZCBzdGVwcGVkIHZlcnRpY2VzLi4uXG5cdC8vIEluY2x1ZGluZyBmcm9udCBmYWNpbmcgdmVydGljZXNcblxuXHR2YXIgcztcblxuXHRmb3IgKCBzID0gMTsgcyA8PSBzdGVwczsgcyArKyApIHtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgdmxlbjsgaSArKyApIHtcblxuXHRcdFx0dmVydCA9IGJldmVsRW5hYmxlZCA/IHNjYWxlUHQyKCB2ZXJ0aWNlc1sgaSBdLCB2ZXJ0aWNlc01vdmVtZW50c1sgaSBdLCBicyApIDogdmVydGljZXNbIGkgXTtcblxuXHRcdFx0aWYgKCAhIGV4dHJ1ZGVCeVBhdGggKSB7XG5cblx0XHRcdFx0diggdmVydC54LCB2ZXJ0LnksIGFtb3VudCAvIHN0ZXBzICogcyApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIHYoIHZlcnQueCwgdmVydC55ICsgZXh0cnVkZVB0c1sgcyAtIDEgXS55LCBleHRydWRlUHRzWyBzIC0gMSBdLnggKTtcblxuXHRcdFx0XHRub3JtYWwuY29weSggc3BsaW5lVHViZS5ub3JtYWxzWyBzIF0gKS5tdWx0aXBseVNjYWxhciggdmVydC54ICk7XG5cdFx0XHRcdGJpbm9ybWFsLmNvcHkoIHNwbGluZVR1YmUuYmlub3JtYWxzWyBzIF0gKS5tdWx0aXBseVNjYWxhciggdmVydC55ICk7XG5cblx0XHRcdFx0cG9zaXRpb24yLmNvcHkoIGV4dHJ1ZGVQdHNbIHMgXSApLmFkZCggbm9ybWFsICkuYWRkKCBiaW5vcm1hbCApO1xuXG5cdFx0XHRcdHYoIHBvc2l0aW9uMi54LCBwb3NpdGlvbjIueSwgcG9zaXRpb24yLnogKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH1cblxuXG5cdC8vIEFkZCBiZXZlbCBzZWdtZW50cyBwbGFuZXNcblxuXHQvL2ZvciAoIGIgPSAxOyBiIDw9IGJldmVsU2VnbWVudHM7IGIgKysgKSB7XG5cdGZvciAoIGIgPSBiZXZlbFNlZ21lbnRzIC0gMTsgYiA+PSAwOyBiIC0tICkge1xuXG5cdFx0dCA9IGIgLyBiZXZlbFNlZ21lbnRzO1xuXHRcdHogPSBiZXZlbFRoaWNrbmVzcyAqIE1hdGguY29zKCB0ICogTWF0aC5QSSAvIDIgKTtcblx0XHRicyA9IGJldmVsU2l6ZSAqIE1hdGguc2luKCB0ICogTWF0aC5QSSAvIDIgKTtcblxuXHRcdC8vIGNvbnRyYWN0IHNoYXBlXG5cblx0XHRmb3IgKCBpID0gMCwgaWwgPSBjb250b3VyLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2ZXJ0ID0gc2NhbGVQdDIoIGNvbnRvdXJbIGkgXSwgY29udG91ck1vdmVtZW50c1sgaSBdLCBicyApO1xuXHRcdFx0diggdmVydC54LCB2ZXJ0LnksIGFtb3VudCArIHogKTtcblxuXHRcdH1cblxuXHRcdC8vIGV4cGFuZCBob2xlc1xuXG5cdFx0Zm9yICggaCA9IDAsIGhsID0gaG9sZXMubGVuZ3RoOyBoIDwgaGw7IGggKysgKSB7XG5cblx0XHRcdGFob2xlID0gaG9sZXNbIGggXTtcblx0XHRcdG9uZUhvbGVNb3ZlbWVudHMgPSBob2xlc01vdmVtZW50c1sgaCBdO1xuXG5cdFx0XHRmb3IgKCBpID0gMCwgaWwgPSBhaG9sZS5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcblxuXHRcdFx0XHR2ZXJ0ID0gc2NhbGVQdDIoIGFob2xlWyBpIF0sIG9uZUhvbGVNb3ZlbWVudHNbIGkgXSwgYnMgKTtcblxuXHRcdFx0XHRpZiAoICEgZXh0cnVkZUJ5UGF0aCApIHtcblxuXHRcdFx0XHRcdHYoIHZlcnQueCwgdmVydC55LCBhbW91bnQgKyB6ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHYoIHZlcnQueCwgdmVydC55ICsgZXh0cnVkZVB0c1sgc3RlcHMgLSAxIF0ueSwgZXh0cnVkZVB0c1sgc3RlcHMgLSAxIF0ueCArIHogKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0LyogRmFjZXMgKi9cblxuXHQvLyBUb3AgYW5kIGJvdHRvbSBmYWNlc1xuXG5cdGJ1aWxkTGlkRmFjZXMoKTtcblxuXHQvLyBTaWRlcyBmYWNlc1xuXG5cdGJ1aWxkU2lkZUZhY2VzKCk7XG5cblxuXHQvLy8vLyAgSW50ZXJuYWwgZnVuY3Rpb25zXG5cblx0ZnVuY3Rpb24gYnVpbGRMaWRGYWNlcygpIHtcblxuXHRcdHZhciBzdGFydCA9IHZlcnRpY2VzQXJyYXkubGVuZ3RoLzM7XG5cblx0XHRpZiAoIGJldmVsRW5hYmxlZCApIHtcblxuXHRcdFx0dmFyIGxheWVyID0gMDsgLy8gc3RlcHMgKyAxXG5cdFx0XHR2YXIgb2Zmc2V0ID0gdmxlbiAqIGxheWVyO1xuXG5cdFx0XHQvLyBCb3R0b20gZmFjZXNcblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBmbGVuOyBpICsrICkge1xuXG5cdFx0XHRcdGZhY2UgPSBmYWNlc1sgaSBdO1xuXHRcdFx0XHRmMyggZmFjZVsgMiBdICsgb2Zmc2V0LCBmYWNlWyAxIF0gKyBvZmZzZXQsIGZhY2VbIDAgXSArIG9mZnNldCApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGxheWVyID0gc3RlcHMgKyBiZXZlbFNlZ21lbnRzICogMjtcblx0XHRcdG9mZnNldCA9IHZsZW4gKiBsYXllcjtcblxuXHRcdFx0Ly8gVG9wIGZhY2VzXG5cblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZmxlbjsgaSArKyApIHtcblxuXHRcdFx0XHRmYWNlID0gZmFjZXNbIGkgXTtcblx0XHRcdFx0ZjMoIGZhY2VbIDAgXSArIG9mZnNldCwgZmFjZVsgMSBdICsgb2Zmc2V0LCBmYWNlWyAyIF0gKyBvZmZzZXQgKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gQm90dG9tIGZhY2VzXG5cblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZmxlbjsgaSArKyApIHtcblxuXHRcdFx0XHRmYWNlID0gZmFjZXNbIGkgXTtcblx0XHRcdFx0ZjMoIGZhY2VbIDIgXSwgZmFjZVsgMSBdLCBmYWNlWyAwIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUb3AgZmFjZXNcblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBmbGVuOyBpICsrICkge1xuXG5cdFx0XHRcdGZhY2UgPSBmYWNlc1sgaSBdO1xuXHRcdFx0XHRmMyggZmFjZVsgMCBdICsgdmxlbiAqIHN0ZXBzLCBmYWNlWyAxIF0gKyB2bGVuICogc3RlcHMsIGZhY2VbIDIgXSArIHZsZW4gKiBzdGVwcyApO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRzY29wZS5hZGRHcm91cCggc3RhcnQsIHZlcnRpY2VzQXJyYXkubGVuZ3RoLzMgLXN0YXJ0LCBvcHRpb25zLm1hdGVyaWFsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1hdGVyaWFsIDogMCk7XG5cblx0fVxuXG5cdC8vIENyZWF0ZSBmYWNlcyBmb3IgdGhlIHotc2lkZXMgb2YgdGhlIHNoYXBlXG5cblx0ZnVuY3Rpb24gYnVpbGRTaWRlRmFjZXMoKSB7XG5cblx0XHR2YXIgc3RhcnQgPSB2ZXJ0aWNlc0FycmF5Lmxlbmd0aC8zO1xuXHRcdHZhciBsYXllcm9mZnNldCA9IDA7XG5cdFx0c2lkZXdhbGxzKCBjb250b3VyLCBsYXllcm9mZnNldCApO1xuXHRcdGxheWVyb2Zmc2V0ICs9IGNvbnRvdXIubGVuZ3RoO1xuXG5cdFx0Zm9yICggaCA9IDAsIGhsID0gaG9sZXMubGVuZ3RoOyBoIDwgaGw7IGggKysgKSB7XG5cblx0XHRcdGFob2xlID0gaG9sZXNbIGggXTtcblx0XHRcdHNpZGV3YWxscyggYWhvbGUsIGxheWVyb2Zmc2V0ICk7XG5cblx0XHRcdC8vLCB0cnVlXG5cdFx0XHRsYXllcm9mZnNldCArPSBhaG9sZS5sZW5ndGg7XG5cblx0XHR9XG5cblxuXHRcdHNjb3BlLmFkZEdyb3VwKCBzdGFydCwgdmVydGljZXNBcnJheS5sZW5ndGgvMyAtc3RhcnQsIG9wdGlvbnMuZXh0cnVkZU1hdGVyaWFsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmV4dHJ1ZGVNYXRlcmlhbCA6IDEpO1xuXG5cblx0fVxuXG5cdGZ1bmN0aW9uIHNpZGV3YWxscyggY29udG91ciwgbGF5ZXJvZmZzZXQgKSB7XG5cblx0XHR2YXIgaiwgaztcblx0XHRpID0gY29udG91ci5sZW5ndGg7XG5cblx0XHR3aGlsZSAoIC0tIGkgPj0gMCApIHtcblxuXHRcdFx0aiA9IGk7XG5cdFx0XHRrID0gaSAtIDE7XG5cdFx0XHRpZiAoIGsgPCAwICkgayA9IGNvbnRvdXIubGVuZ3RoIC0gMTtcblxuXHRcdFx0Ly9jb25zb2xlLmxvZygnYicsIGksaiwgaS0xLCBrLHZlcnRpY2VzLmxlbmd0aCk7XG5cblx0XHRcdHZhciBzID0gMCxcblx0XHRcdFx0c2wgPSBzdGVwcyArIGJldmVsU2VnbWVudHMgKiAyO1xuXG5cdFx0XHRmb3IgKCBzID0gMDsgcyA8IHNsOyBzICsrICkge1xuXG5cdFx0XHRcdHZhciBzbGVuMSA9IHZsZW4gKiBzO1xuXHRcdFx0XHR2YXIgc2xlbjIgPSB2bGVuICogKCBzICsgMSApO1xuXG5cdFx0XHRcdHZhciBhID0gbGF5ZXJvZmZzZXQgKyBqICsgc2xlbjEsXG5cdFx0XHRcdFx0YiA9IGxheWVyb2Zmc2V0ICsgayArIHNsZW4xLFxuXHRcdFx0XHRcdGMgPSBsYXllcm9mZnNldCArIGsgKyBzbGVuMixcblx0XHRcdFx0XHRkID0gbGF5ZXJvZmZzZXQgKyBqICsgc2xlbjI7XG5cblx0XHRcdFx0ZjQoIGEsIGIsIGMsIGQsIGNvbnRvdXIsIHMsIHNsLCBqLCBrICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0ZnVuY3Rpb24gdiggeCwgeSwgeiApIHtcblxuXHRcdHBsYWNlaG9sZGVyLnB1c2goIHggKTtcblx0XHRwbGFjZWhvbGRlci5wdXNoKCB5ICk7XG5cdFx0cGxhY2Vob2xkZXIucHVzaCggeiApO1xuXG5cdH1cblxuXG5cdGZ1bmN0aW9uIGYzKCBhLCBiLCBjICkge1xuXG5cdFx0YWRkVmVydGV4KCBhICk7XG5cdFx0YWRkVmVydGV4KCBiICk7XG5cdFx0YWRkVmVydGV4KCBjICk7XG5cblx0XHR2YXIgbmV4dEluZGV4ID0gdmVydGljZXNBcnJheS5sZW5ndGggLyAzO1xuXHRcdHZhciB1dnMgPSB1dmdlbi5nZW5lcmF0ZVRvcFVWKCBzY29wZSwgdmVydGljZXNBcnJheSwgbmV4dEluZGV4IC0gMywgbmV4dEluZGV4IC0gMiwgbmV4dEluZGV4IC0gMSApO1xuXG5cdFx0YWRkVVYoIHV2c1sgMCBdICk7XG5cdFx0YWRkVVYoIHV2c1sgMSBdICk7XG5cdFx0YWRkVVYoIHV2c1sgMiBdICk7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGY0KCBhLCBiLCBjLCBkLCB3YWxsQ29udG91ciwgc3RlcEluZGV4LCBzdGVwc0xlbmd0aCwgY29udG91ckluZGV4MSwgY29udG91ckluZGV4MiApIHtcblxuXHRcdGFkZFZlcnRleCggYSApO1xuXHRcdGFkZFZlcnRleCggYiApO1xuXHRcdGFkZFZlcnRleCggZCApO1xuXG5cdFx0YWRkVmVydGV4KCBiICk7XG5cdFx0YWRkVmVydGV4KCBjICk7XG5cdFx0YWRkVmVydGV4KCBkICk7XG5cblxuXHRcdHZhciBuZXh0SW5kZXggPSB2ZXJ0aWNlc0FycmF5Lmxlbmd0aCAvIDM7XG5cdFx0dmFyIHV2cyA9IHV2Z2VuLmdlbmVyYXRlU2lkZVdhbGxVViggc2NvcGUsIHZlcnRpY2VzQXJyYXksIG5leHRJbmRleCAtIDYsIG5leHRJbmRleCAtIDMsIG5leHRJbmRleCAtIDIsIG5leHRJbmRleCAtIDEgKTtcblxuXHRcdGFkZFVWKCB1dnNbIDAgXSApO1xuXHRcdGFkZFVWKCB1dnNbIDEgXSApO1xuXHRcdGFkZFVWKCB1dnNbIDMgXSApO1xuXG5cdFx0YWRkVVYoIHV2c1sgMSBdICk7XG5cdFx0YWRkVVYoIHV2c1sgMiBdICk7XG5cdFx0YWRkVVYoIHV2c1sgMyBdICk7XG5cblx0fVxuXG5cdGZ1bmN0aW9uIGFkZFZlcnRleCggaW5kZXggKSB7XG5cblx0XHRpbmRpY2VzQXJyYXkucHVzaCggdmVydGljZXNBcnJheS5sZW5ndGggLyAzICk7XG5cdFx0dmVydGljZXNBcnJheS5wdXNoKCBwbGFjZWhvbGRlclsgaW5kZXggKiAzICsgMCBdICk7XG5cdFx0dmVydGljZXNBcnJheS5wdXNoKCBwbGFjZWhvbGRlclsgaW5kZXggKiAzICsgMSBdICk7XG5cdFx0dmVydGljZXNBcnJheS5wdXNoKCBwbGFjZWhvbGRlclsgaW5kZXggKiAzICsgMiBdICk7XG5cblx0fVxuXG5cblx0ZnVuY3Rpb24gYWRkVVYoIHZlY3RvcjIgKSB7XG5cblx0XHR1dkFycmF5LnB1c2goIHZlY3RvcjIueCApO1xuXHRcdHV2QXJyYXkucHVzaCggdmVjdG9yMi55ICk7XG5cblx0fVxuXG5cdGlmICggISBvcHRpb25zLmFycmF5cyApIHtcblxuXHRcdHRoaXMuc2V0SW5kZXgoIGluZGljZXNBcnJheSApO1xuXHRcdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXNBcnJheSwgMyApICk7XG5cdFx0dGhpcy5hZGRBdHRyaWJ1dGUoICd1dicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBvcHRpb25zLmFycmF5cy51diwgMiApICk7XG5cblx0fVxuXG59O1xuXG5FeHRydWRlR2VvbWV0cnkuV29ybGRVVkdlbmVyYXRvciA9IHtcblxuXHRnZW5lcmF0ZVRvcFVWOiBmdW5jdGlvbiAoIGdlb21ldHJ5LCB2ZXJ0aWNlcywgaW5kZXhBLCBpbmRleEIsIGluZGV4QyApIHtcblxuXHRcdHZhciBhX3ggPSB2ZXJ0aWNlc1sgaW5kZXhBICogMyBdO1xuXHRcdHZhciBhX3kgPSB2ZXJ0aWNlc1sgaW5kZXhBICogMyArIDEgXTtcblx0XHR2YXIgYl94ID0gdmVydGljZXNbIGluZGV4QiAqIDMgXTtcblx0XHR2YXIgYl95ID0gdmVydGljZXNbIGluZGV4QiAqIDMgKyAxIF07XG5cdFx0dmFyIGNfeCA9IHZlcnRpY2VzWyBpbmRleEMgKiAzIF07XG5cdFx0dmFyIGNfeSA9IHZlcnRpY2VzWyBpbmRleEMgKiAzICsgMSBdO1xuXG5cdFx0cmV0dXJuIFtcblx0XHRcdG5ldyBWZWN0b3IyKCBhX3gsIGFfeSApLFxuXHRcdFx0bmV3IFZlY3RvcjIoIGJfeCwgYl95ICksXG5cdFx0XHRuZXcgVmVjdG9yMiggY194LCBjX3kgKVxuXHRcdF07XG5cblx0fSxcblxuXHRnZW5lcmF0ZVNpZGVXYWxsVVY6IGZ1bmN0aW9uICggZ2VvbWV0cnksIHZlcnRpY2VzLCBpbmRleEEsIGluZGV4QiwgaW5kZXhDLCBpbmRleEQgKSB7XG5cblx0XHR2YXIgYV94ID0gdmVydGljZXNbIGluZGV4QSAqIDMgXTtcblx0XHR2YXIgYV95ID0gdmVydGljZXNbIGluZGV4QSAqIDMgKyAxIF07XG5cdFx0dmFyIGFfeiA9IHZlcnRpY2VzWyBpbmRleEEgKiAzICsgMiBdO1xuXHRcdHZhciBiX3ggPSB2ZXJ0aWNlc1sgaW5kZXhCICogMyBdO1xuXHRcdHZhciBiX3kgPSB2ZXJ0aWNlc1sgaW5kZXhCICogMyArIDEgXTtcblx0XHR2YXIgYl96ID0gdmVydGljZXNbIGluZGV4QiAqIDMgKyAyIF07XG5cdFx0dmFyIGNfeCA9IHZlcnRpY2VzWyBpbmRleEMgKiAzIF07XG5cdFx0dmFyIGNfeSA9IHZlcnRpY2VzWyBpbmRleEMgKiAzICsgMSBdO1xuXHRcdHZhciBjX3ogPSB2ZXJ0aWNlc1sgaW5kZXhDICogMyArIDIgXTtcblx0XHR2YXIgZF94ID0gdmVydGljZXNbIGluZGV4RCAqIDMgXTtcblx0XHR2YXIgZF95ID0gdmVydGljZXNbIGluZGV4RCAqIDMgKyAxIF07XG5cdFx0dmFyIGRfeiA9IHZlcnRpY2VzWyBpbmRleEQgKiAzICsgMiBdO1xuXG5cdFx0aWYgKCBNYXRoLmFicyggYV95IC0gYl95ICkgPCAwLjAxICkge1xuXG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRuZXcgVmVjdG9yMiggYV94LCAxIC0gYV96ICksXG5cdFx0XHRcdG5ldyBWZWN0b3IyKCBiX3gsIDEgLSBiX3ogKSxcblx0XHRcdFx0bmV3IFZlY3RvcjIoIGNfeCwgMSAtIGNfeiApLFxuXHRcdFx0XHRuZXcgVmVjdG9yMiggZF94LCAxIC0gZF96IClcblx0XHRcdF07XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRuZXcgVmVjdG9yMiggYV95LCAxIC0gYV96ICksXG5cdFx0XHRcdG5ldyBWZWN0b3IyKCBiX3ksIDEgLSBiX3ogKSxcblx0XHRcdFx0bmV3IFZlY3RvcjIoIGNfeSwgMSAtIGNfeiApLFxuXHRcdFx0XHRuZXcgVmVjdG9yMiggZF95LCAxIC0gZF96IClcblx0XHRcdF07XG5cblx0XHR9XG5cblx0fVxufTtcblxuLyoqXG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwOi8vd3d3LmxhYjRnYW1lcy5uZXQveno4NS9ibG9nXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICpcbiAqIFRleHQgPSAzRCBUZXh0XG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBmb250OiA8VEhSRUUuRm9udD4sIC8vIGZvbnRcbiAqXG4gKiAgc2l6ZTogPGZsb2F0PiwgLy8gc2l6ZSBvZiB0aGUgdGV4dFxuICogIGhlaWdodDogPGZsb2F0PiwgLy8gdGhpY2tuZXNzIHRvIGV4dHJ1ZGUgdGV4dFxuICogIGN1cnZlU2VnbWVudHM6IDxpbnQ+LCAvLyBudW1iZXIgb2YgcG9pbnRzIG9uIHRoZSBjdXJ2ZXNcbiAqXG4gKiAgYmV2ZWxFbmFibGVkOiA8Ym9vbD4sIC8vIHR1cm4gb24gYmV2ZWxcbiAqICBiZXZlbFRoaWNrbmVzczogPGZsb2F0PiwgLy8gaG93IGRlZXAgaW50byB0ZXh0IGJldmVsIGdvZXNcbiAqICBiZXZlbFNpemU6IDxmbG9hdD4gLy8gaG93IGZhciBmcm9tIHRleHQgb3V0bGluZSBpcyBiZXZlbFxuICogfVxuICovXG5cbi8vIFRleHRHZW9tZXRyeVxuXG5mdW5jdGlvbiBUZXh0R2VvbWV0cnkoICB0ZXh0LCBwYXJhbWV0ZXJzICkge1xuXG5cdEdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVGV4dEdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0dGV4dDogdGV4dCxcblx0XHRwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJzXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBUZXh0QnVmZmVyR2VvbWV0cnkoIHRleHQsIHBhcmFtZXRlcnMgKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5UZXh0R2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5UZXh0R2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVGV4dEdlb21ldHJ5O1xuXG4vLyBUZXh0QnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gVGV4dEJ1ZmZlckdlb21ldHJ5KCB0ZXh0LCBwYXJhbWV0ZXJzICkge1xuXG5cdHBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzIHx8IHt9O1xuXG5cdHZhciBmb250ID0gcGFyYW1ldGVycy5mb250O1xuXG5cdGlmICggKCBmb250ICYmIGZvbnQuaXNGb250ICkgPT09IGZhbHNlICkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLlRleHRHZW9tZXRyeTogZm9udCBwYXJhbWV0ZXIgaXMgbm90IGFuIGluc3RhbmNlIG9mIFRIUkVFLkZvbnQuJyApO1xuXHRcdHJldHVybiBuZXcgR2VvbWV0cnkoKTtcblxuXHR9XG5cblx0dmFyIHNoYXBlcyA9IGZvbnQuZ2VuZXJhdGVTaGFwZXMoIHRleHQsIHBhcmFtZXRlcnMuc2l6ZSwgcGFyYW1ldGVycy5jdXJ2ZVNlZ21lbnRzICk7XG5cblx0Ly8gdHJhbnNsYXRlIHBhcmFtZXRlcnMgdG8gRXh0cnVkZUdlb21ldHJ5IEFQSVxuXG5cdHBhcmFtZXRlcnMuYW1vdW50ID0gcGFyYW1ldGVycy5oZWlnaHQgIT09IHVuZGVmaW5lZCA/IHBhcmFtZXRlcnMuaGVpZ2h0IDogNTA7XG5cblx0Ly8gZGVmYXVsdHNcblxuXHRpZiAoIHBhcmFtZXRlcnMuYmV2ZWxUaGlja25lc3MgPT09IHVuZGVmaW5lZCApIHBhcmFtZXRlcnMuYmV2ZWxUaGlja25lc3MgPSAxMDtcblx0aWYgKCBwYXJhbWV0ZXJzLmJldmVsU2l6ZSA9PT0gdW5kZWZpbmVkICkgcGFyYW1ldGVycy5iZXZlbFNpemUgPSA4O1xuXHRpZiAoIHBhcmFtZXRlcnMuYmV2ZWxFbmFibGVkID09PSB1bmRlZmluZWQgKSBwYXJhbWV0ZXJzLmJldmVsRW5hYmxlZCA9IGZhbHNlO1xuXG5cdEV4dHJ1ZGVCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzLCBzaGFwZXMsIHBhcmFtZXRlcnMgKTtcblxuXHR0aGlzLnR5cGUgPSAnVGV4dEJ1ZmZlckdlb21ldHJ5JztcblxufVxuXG5UZXh0QnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggRXh0cnVkZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuVGV4dEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFRleHRCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBiZW5hYWRhbXMgLyBodHRwczovL3R3aXR0ZXIuY29tL2Jlbl9hX2FkYW1zXG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbi8vIFNwaGVyZUdlb21ldHJ5XG5cbmZ1bmN0aW9uIFNwaGVyZUdlb21ldHJ5KCByYWRpdXMsIHdpZHRoU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCBwaGlTdGFydCwgcGhpTGVuZ3RoLCB0aGV0YVN0YXJ0LCB0aGV0YUxlbmd0aCApIHtcblxuXHRHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ1NwaGVyZUdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzOiByYWRpdXMsXG5cdFx0d2lkdGhTZWdtZW50czogd2lkdGhTZWdtZW50cyxcblx0XHRoZWlnaHRTZWdtZW50czogaGVpZ2h0U2VnbWVudHMsXG5cdFx0cGhpU3RhcnQ6IHBoaVN0YXJ0LFxuXHRcdHBoaUxlbmd0aDogcGhpTGVuZ3RoLFxuXHRcdHRoZXRhU3RhcnQ6IHRoZXRhU3RhcnQsXG5cdFx0dGhldGFMZW5ndGg6IHRoZXRhTGVuZ3RoXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBTcGhlcmVCdWZmZXJHZW9tZXRyeSggcmFkaXVzLCB3aWR0aFNlZ21lbnRzLCBoZWlnaHRTZWdtZW50cywgcGhpU3RhcnQsIHBoaUxlbmd0aCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSApO1xuXHR0aGlzLm1lcmdlVmVydGljZXMoKTtcblxufVxuXG5TcGhlcmVHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcblNwaGVyZUdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFNwaGVyZUdlb21ldHJ5O1xuXG4vLyBTcGhlcmVCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBTcGhlcmVCdWZmZXJHZW9tZXRyeSggcmFkaXVzLCB3aWR0aFNlZ21lbnRzLCBoZWlnaHRTZWdtZW50cywgcGhpU3RhcnQsIHBoaUxlbmd0aCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdTcGhlcmVCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdHdpZHRoU2VnbWVudHM6IHdpZHRoU2VnbWVudHMsXG5cdFx0aGVpZ2h0U2VnbWVudHM6IGhlaWdodFNlZ21lbnRzLFxuXHRcdHBoaVN0YXJ0OiBwaGlTdGFydCxcblx0XHRwaGlMZW5ndGg6IHBoaUxlbmd0aCxcblx0XHR0aGV0YVN0YXJ0OiB0aGV0YVN0YXJ0LFxuXHRcdHRoZXRhTGVuZ3RoOiB0aGV0YUxlbmd0aFxuXHR9O1xuXG5cdHJhZGl1cyA9IHJhZGl1cyB8fCA1MDtcblxuXHR3aWR0aFNlZ21lbnRzID0gTWF0aC5tYXgoIDMsIE1hdGguZmxvb3IoIHdpZHRoU2VnbWVudHMgKSB8fCA4ICk7XG5cdGhlaWdodFNlZ21lbnRzID0gTWF0aC5tYXgoIDIsIE1hdGguZmxvb3IoIGhlaWdodFNlZ21lbnRzICkgfHwgNiApO1xuXG5cdHBoaVN0YXJ0ID0gcGhpU3RhcnQgIT09IHVuZGVmaW5lZCA/IHBoaVN0YXJ0IDogMDtcblx0cGhpTGVuZ3RoID0gcGhpTGVuZ3RoICE9PSB1bmRlZmluZWQgPyBwaGlMZW5ndGggOiBNYXRoLlBJICogMjtcblxuXHR0aGV0YVN0YXJ0ID0gdGhldGFTdGFydCAhPT0gdW5kZWZpbmVkID8gdGhldGFTdGFydCA6IDA7XG5cdHRoZXRhTGVuZ3RoID0gdGhldGFMZW5ndGggIT09IHVuZGVmaW5lZCA/IHRoZXRhTGVuZ3RoIDogTWF0aC5QSTtcblxuXHR2YXIgdGhldGFFbmQgPSB0aGV0YVN0YXJ0ICsgdGhldGFMZW5ndGg7XG5cblx0dmFyIGl4LCBpeTtcblxuXHR2YXIgaW5kZXggPSAwO1xuXHR2YXIgZ3JpZCA9IFtdO1xuXG5cdHZhciB2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgbm9ybWFsID0gbmV3IFZlY3RvcjMoKTtcblxuXHQvLyBidWZmZXJzXG5cblx0dmFyIGluZGljZXMgPSBbXTtcblx0dmFyIHZlcnRpY2VzID0gW107XG5cdHZhciBub3JtYWxzID0gW107XG5cdHZhciB1dnMgPSBbXTtcblxuXHQvLyBnZW5lcmF0ZSB2ZXJ0aWNlcywgbm9ybWFscyBhbmQgdXZzXG5cblx0Zm9yICggaXkgPSAwOyBpeSA8PSBoZWlnaHRTZWdtZW50czsgaXkgKysgKSB7XG5cblx0XHR2YXIgdmVydGljZXNSb3cgPSBbXTtcblxuXHRcdHZhciB2ID0gaXkgLyBoZWlnaHRTZWdtZW50cztcblxuXHRcdGZvciAoIGl4ID0gMDsgaXggPD0gd2lkdGhTZWdtZW50czsgaXggKysgKSB7XG5cblx0XHRcdHZhciB1ID0gaXggLyB3aWR0aFNlZ21lbnRzO1xuXG5cdFx0XHQvLyB2ZXJ0ZXhcblxuXHRcdFx0dmVydGV4LnggPSAtIHJhZGl1cyAqIE1hdGguY29zKCBwaGlTdGFydCArIHUgKiBwaGlMZW5ndGggKSAqIE1hdGguc2luKCB0aGV0YVN0YXJ0ICsgdiAqIHRoZXRhTGVuZ3RoICk7XG5cdFx0XHR2ZXJ0ZXgueSA9IHJhZGl1cyAqIE1hdGguY29zKCB0aGV0YVN0YXJ0ICsgdiAqIHRoZXRhTGVuZ3RoICk7XG5cdFx0XHR2ZXJ0ZXgueiA9IHJhZGl1cyAqIE1hdGguc2luKCBwaGlTdGFydCArIHUgKiBwaGlMZW5ndGggKSAqIE1hdGguc2luKCB0aGV0YVN0YXJ0ICsgdiAqIHRoZXRhTGVuZ3RoICk7XG5cblx0XHRcdHZlcnRpY2VzLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKTtcblxuXHRcdFx0Ly8gbm9ybWFsXG5cblx0XHRcdG5vcm1hbC5zZXQoIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKS5ub3JtYWxpemUoKTtcblx0XHRcdG5vcm1hbHMucHVzaCggbm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1dnMucHVzaCggdSwgMSAtIHYgKTtcblxuXHRcdFx0dmVydGljZXNSb3cucHVzaCggaW5kZXggKysgKTtcblxuXHRcdH1cblxuXHRcdGdyaWQucHVzaCggdmVydGljZXNSb3cgKTtcblxuXHR9XG5cblx0Ly8gaW5kaWNlc1xuXG5cdGZvciAoIGl5ID0gMDsgaXkgPCBoZWlnaHRTZWdtZW50czsgaXkgKysgKSB7XG5cblx0XHRmb3IgKCBpeCA9IDA7IGl4IDwgd2lkdGhTZWdtZW50czsgaXggKysgKSB7XG5cblx0XHRcdHZhciBhID0gZ3JpZFsgaXkgXVsgaXggKyAxIF07XG5cdFx0XHR2YXIgYiA9IGdyaWRbIGl5IF1bIGl4IF07XG5cdFx0XHR2YXIgYyA9IGdyaWRbIGl5ICsgMSBdWyBpeCBdO1xuXHRcdFx0dmFyIGQgPSBncmlkWyBpeSArIDEgXVsgaXggKyAxIF07XG5cblx0XHRcdGlmICggaXkgIT09IDAgfHwgdGhldGFTdGFydCA+IDAgKSBpbmRpY2VzLnB1c2goIGEsIGIsIGQgKTtcblx0XHRcdGlmICggaXkgIT09IGhlaWdodFNlZ21lbnRzIC0gMSB8fCB0aGV0YUVuZCA8IE1hdGguUEkgKSBpbmRpY2VzLnB1c2goIGIsIGMsIGQgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gYnVpbGQgZ2VvbWV0cnlcblxuXHR0aGlzLnNldEluZGV4KCBpbmRpY2VzICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ25vcm1hbCcsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBub3JtYWxzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICd1dicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB1dnMsIDIgKSApO1xuXG59XG5cblNwaGVyZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuU3BoZXJlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU3BoZXJlQnVmZmVyR2VvbWV0cnk7XG5cbi8qKlxuICogQGF1dGhvciBLYWxlYiBNdXJwaHlcbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gUmluZ0dlb21ldHJ5XG5cbmZ1bmN0aW9uIFJpbmdHZW9tZXRyeSggaW5uZXJSYWRpdXMsIG91dGVyUmFkaXVzLCB0aGV0YVNlZ21lbnRzLCBwaGlTZWdtZW50cywgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdSaW5nR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRpbm5lclJhZGl1czogaW5uZXJSYWRpdXMsXG5cdFx0b3V0ZXJSYWRpdXM6IG91dGVyUmFkaXVzLFxuXHRcdHRoZXRhU2VnbWVudHM6IHRoZXRhU2VnbWVudHMsXG5cdFx0cGhpU2VnbWVudHM6IHBoaVNlZ21lbnRzLFxuXHRcdHRoZXRhU3RhcnQ6IHRoZXRhU3RhcnQsXG5cdFx0dGhldGFMZW5ndGg6IHRoZXRhTGVuZ3RoXG5cdH07XG5cblx0dGhpcy5mcm9tQnVmZmVyR2VvbWV0cnkoIG5ldyBSaW5nQnVmZmVyR2VvbWV0cnkoIGlubmVyUmFkaXVzLCBvdXRlclJhZGl1cywgdGhldGFTZWdtZW50cywgcGhpU2VnbWVudHMsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuUmluZ0dlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEdlb21ldHJ5LnByb3RvdHlwZSApO1xuUmluZ0dlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFJpbmdHZW9tZXRyeTtcblxuLy8gUmluZ0J1ZmZlckdlb21ldHJ5XG5cbmZ1bmN0aW9uIFJpbmdCdWZmZXJHZW9tZXRyeSggaW5uZXJSYWRpdXMsIG91dGVyUmFkaXVzLCB0aGV0YVNlZ21lbnRzLCBwaGlTZWdtZW50cywgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdSaW5nQnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRpbm5lclJhZGl1czogaW5uZXJSYWRpdXMsXG5cdFx0b3V0ZXJSYWRpdXM6IG91dGVyUmFkaXVzLFxuXHRcdHRoZXRhU2VnbWVudHM6IHRoZXRhU2VnbWVudHMsXG5cdFx0cGhpU2VnbWVudHM6IHBoaVNlZ21lbnRzLFxuXHRcdHRoZXRhU3RhcnQ6IHRoZXRhU3RhcnQsXG5cdFx0dGhldGFMZW5ndGg6IHRoZXRhTGVuZ3RoXG5cdH07XG5cblx0aW5uZXJSYWRpdXMgPSBpbm5lclJhZGl1cyB8fCAyMDtcblx0b3V0ZXJSYWRpdXMgPSBvdXRlclJhZGl1cyB8fCA1MDtcblxuXHR0aGV0YVN0YXJ0ID0gdGhldGFTdGFydCAhPT0gdW5kZWZpbmVkID8gdGhldGFTdGFydCA6IDA7XG5cdHRoZXRhTGVuZ3RoID0gdGhldGFMZW5ndGggIT09IHVuZGVmaW5lZCA/IHRoZXRhTGVuZ3RoIDogTWF0aC5QSSAqIDI7XG5cblx0dGhldGFTZWdtZW50cyA9IHRoZXRhU2VnbWVudHMgIT09IHVuZGVmaW5lZCA/IE1hdGgubWF4KCAzLCB0aGV0YVNlZ21lbnRzICkgOiA4O1xuXHRwaGlTZWdtZW50cyA9IHBoaVNlZ21lbnRzICE9PSB1bmRlZmluZWQgPyBNYXRoLm1heCggMSwgcGhpU2VnbWVudHMgKSA6IDE7XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0Ly8gc29tZSBoZWxwZXIgdmFyaWFibGVzXG5cblx0dmFyIHNlZ21lbnQ7XG5cdHZhciByYWRpdXMgPSBpbm5lclJhZGl1cztcblx0dmFyIHJhZGl1c1N0ZXAgPSAoICggb3V0ZXJSYWRpdXMgLSBpbm5lclJhZGl1cyApIC8gcGhpU2VnbWVudHMgKTtcblx0dmFyIHZlcnRleCA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciB1diA9IG5ldyBWZWN0b3IyKCk7XG5cdHZhciBqLCBpO1xuXG5cdC8vIGdlbmVyYXRlIHZlcnRpY2VzLCBub3JtYWxzIGFuZCB1dnNcblxuXHRmb3IgKCBqID0gMDsgaiA8PSBwaGlTZWdtZW50czsgaiArKyApIHtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDw9IHRoZXRhU2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdC8vIHZhbHVlcyBhcmUgZ2VuZXJhdGUgZnJvbSB0aGUgaW5zaWRlIG9mIHRoZSByaW5nIHRvIHRoZSBvdXRzaWRlXG5cblx0XHRcdHNlZ21lbnQgPSB0aGV0YVN0YXJ0ICsgaSAvIHRoZXRhU2VnbWVudHMgKiB0aGV0YUxlbmd0aDtcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHZlcnRleC54ID0gcmFkaXVzICogTWF0aC5jb3MoIHNlZ21lbnQgKTtcblx0XHRcdHZlcnRleC55ID0gcmFkaXVzICogTWF0aC5zaW4oIHNlZ21lbnQgKTtcblxuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0XHQvLyBub3JtYWxcblxuXHRcdFx0bm9ybWFscy5wdXNoKCAwLCAwLCAxICk7XG5cblx0XHRcdC8vIHV2XG5cblx0XHRcdHV2LnggPSAoIHZlcnRleC54IC8gb3V0ZXJSYWRpdXMgKyAxICkgLyAyO1xuXHRcdFx0dXYueSA9ICggdmVydGV4LnkgLyBvdXRlclJhZGl1cyArIDEgKSAvIDI7XG5cblx0XHRcdHV2cy5wdXNoKCB1di54LCB1di55ICk7XG5cblx0XHR9XG5cblx0XHQvLyBpbmNyZWFzZSB0aGUgcmFkaXVzIGZvciBuZXh0IHJvdyBvZiB2ZXJ0aWNlc1xuXG5cdFx0cmFkaXVzICs9IHJhZGl1c1N0ZXA7XG5cblx0fVxuXG5cdC8vIGluZGljZXNcblxuXHRmb3IgKCBqID0gMDsgaiA8IHBoaVNlZ21lbnRzOyBqICsrICkge1xuXG5cdFx0dmFyIHRoZXRhU2VnbWVudExldmVsID0gaiAqICggdGhldGFTZWdtZW50cyArIDEgKTtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgdGhldGFTZWdtZW50czsgaSArKyApIHtcblxuXHRcdFx0c2VnbWVudCA9IGkgKyB0aGV0YVNlZ21lbnRMZXZlbDtcblxuXHRcdFx0dmFyIGEgPSBzZWdtZW50O1xuXHRcdFx0dmFyIGIgPSBzZWdtZW50ICsgdGhldGFTZWdtZW50cyArIDE7XG5cdFx0XHR2YXIgYyA9IHNlZ21lbnQgKyB0aGV0YVNlZ21lbnRzICsgMjtcblx0XHRcdHZhciBkID0gc2VnbWVudCArIDE7XG5cblx0XHRcdC8vIGZhY2VzXG5cblx0XHRcdGluZGljZXMucHVzaCggYSwgYiwgZCApO1xuXHRcdFx0aW5kaWNlcy5wdXNoKCBiLCBjLCBkICk7XG5cblx0XHR9XG5cblx0fVxuXG5cdC8vIGJ1aWxkIGdlb21ldHJ5XG5cblx0dGhpcy5zZXRJbmRleCggaW5kaWNlcyApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggbm9ybWFscywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkgKTtcblxufVxuXG5SaW5nQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5SaW5nQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUmluZ0J1ZmZlckdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3IgYXN0cm9kdWQgLyBodHRwOi8vYXN0cm9kdWQuaXNncmVhdC5vcmcvXG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwczovL2dpdGh1Yi5jb20veno4NVxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG4vLyBMYXRoZUdlb21ldHJ5XG5cbmZ1bmN0aW9uIExhdGhlR2VvbWV0cnkoIHBvaW50cywgc2VnbWVudHMsIHBoaVN0YXJ0LCBwaGlMZW5ndGggKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdMYXRoZUdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cG9pbnRzOiBwb2ludHMsXG5cdFx0c2VnbWVudHM6IHNlZ21lbnRzLFxuXHRcdHBoaVN0YXJ0OiBwaGlTdGFydCxcblx0XHRwaGlMZW5ndGg6IHBoaUxlbmd0aFxuXHR9O1xuXG5cdHRoaXMuZnJvbUJ1ZmZlckdlb21ldHJ5KCBuZXcgTGF0aGVCdWZmZXJHZW9tZXRyeSggcG9pbnRzLCBzZWdtZW50cywgcGhpU3RhcnQsIHBoaUxlbmd0aCApICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cbkxhdGhlR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5MYXRoZUdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhdGhlR2VvbWV0cnk7XG5cbi8vIExhdGhlQnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gTGF0aGVCdWZmZXJHZW9tZXRyeSggcG9pbnRzLCBzZWdtZW50cywgcGhpU3RhcnQsIHBoaUxlbmd0aCApIHtcblxuXHRCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0xhdGhlQnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRwb2ludHM6IHBvaW50cyxcblx0XHRzZWdtZW50czogc2VnbWVudHMsXG5cdFx0cGhpU3RhcnQ6IHBoaVN0YXJ0LFxuXHRcdHBoaUxlbmd0aDogcGhpTGVuZ3RoXG5cdH07XG5cblx0c2VnbWVudHMgPSBNYXRoLmZsb29yKCBzZWdtZW50cyApIHx8IDEyO1xuXHRwaGlTdGFydCA9IHBoaVN0YXJ0IHx8IDA7XG5cdHBoaUxlbmd0aCA9IHBoaUxlbmd0aCB8fCBNYXRoLlBJICogMjtcblxuXHQvLyBjbGFtcCBwaGlMZW5ndGggc28gaXQncyBpbiByYW5nZSBvZiBbIDAsIDJQSSBdXG5cblx0cGhpTGVuZ3RoID0gX01hdGguY2xhbXAoIHBoaUxlbmd0aCwgMCwgTWF0aC5QSSAqIDIgKTtcblxuXG5cdC8vIGJ1ZmZlcnNcblxuXHR2YXIgaW5kaWNlcyA9IFtdO1xuXHR2YXIgdmVydGljZXMgPSBbXTtcblx0dmFyIHV2cyA9IFtdO1xuXG5cdC8vIGhlbHBlciB2YXJpYWJsZXNcblxuXHR2YXIgYmFzZTtcblx0dmFyIGludmVyc2VTZWdtZW50cyA9IDEuMCAvIHNlZ21lbnRzO1xuXHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIHV2ID0gbmV3IFZlY3RvcjIoKTtcblx0dmFyIGksIGo7XG5cblx0Ly8gZ2VuZXJhdGUgdmVydGljZXMgYW5kIHV2c1xuXG5cdGZvciAoIGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0dmFyIHBoaSA9IHBoaVN0YXJ0ICsgaSAqIGludmVyc2VTZWdtZW50cyAqIHBoaUxlbmd0aDtcblxuXHRcdHZhciBzaW4gPSBNYXRoLnNpbiggcGhpICk7XG5cdFx0dmFyIGNvcyA9IE1hdGguY29zKCBwaGkgKTtcblxuXHRcdGZvciAoIGogPSAwOyBqIDw9ICggcG9pbnRzLmxlbmd0aCAtIDEgKTsgaiArKyApIHtcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHZlcnRleC54ID0gcG9pbnRzWyBqIF0ueCAqIHNpbjtcblx0XHRcdHZlcnRleC55ID0gcG9pbnRzWyBqIF0ueTtcblx0XHRcdHZlcnRleC56ID0gcG9pbnRzWyBqIF0ueCAqIGNvcztcblxuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1di54ID0gaSAvIHNlZ21lbnRzO1xuXHRcdFx0dXYueSA9IGogLyAoIHBvaW50cy5sZW5ndGggLSAxICk7XG5cblx0XHRcdHV2cy5wdXNoKCB1di54LCB1di55ICk7XG5cblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gaW5kaWNlc1xuXG5cdGZvciAoIGkgPSAwOyBpIDwgc2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRmb3IgKCBqID0gMDsgaiA8ICggcG9pbnRzLmxlbmd0aCAtIDEgKTsgaiArKyApIHtcblxuXHRcdFx0YmFzZSA9IGogKyBpICogcG9pbnRzLmxlbmd0aDtcblxuXHRcdFx0dmFyIGEgPSBiYXNlO1xuXHRcdFx0dmFyIGIgPSBiYXNlICsgcG9pbnRzLmxlbmd0aDtcblx0XHRcdHZhciBjID0gYmFzZSArIHBvaW50cy5sZW5ndGggKyAxO1xuXHRcdFx0dmFyIGQgPSBiYXNlICsgMTtcblxuXHRcdFx0Ly8gZmFjZXNcblxuXHRcdFx0aW5kaWNlcy5wdXNoKCBhLCBiLCBkICk7XG5cdFx0XHRpbmRpY2VzLnB1c2goIGIsIGMsIGQgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Ly8gYnVpbGQgZ2VvbWV0cnlcblxuXHR0aGlzLnNldEluZGV4KCBpbmRpY2VzICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHV2cywgMiApICk7XG5cblx0Ly8gZ2VuZXJhdGUgbm9ybWFsc1xuXG5cdHRoaXMuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtcblxuXHQvLyBpZiB0aGUgZ2VvbWV0cnkgaXMgY2xvc2VkLCB3ZSBuZWVkIHRvIGF2ZXJhZ2UgdGhlIG5vcm1hbHMgYWxvbmcgdGhlIHNlYW0uXG5cdC8vIGJlY2F1c2UgdGhlIGNvcnJlc3BvbmRpbmcgdmVydGljZXMgYXJlIGlkZW50aWNhbCAoYnV0IHN0aWxsIGhhdmUgZGlmZmVyZW50IFVWcykuXG5cblx0aWYgKCBwaGlMZW5ndGggPT09IE1hdGguUEkgKiAyICkge1xuXG5cdFx0dmFyIG5vcm1hbHMgPSB0aGlzLmF0dHJpYnV0ZXMubm9ybWFsLmFycmF5O1xuXHRcdHZhciBuMSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIG4yID0gbmV3IFZlY3RvcjMoKTtcblx0XHR2YXIgbiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHQvLyB0aGlzIGlzIHRoZSBidWZmZXIgb2Zmc2V0IGZvciB0aGUgbGFzdCBsaW5lIG9mIHZlcnRpY2VzXG5cblx0XHRiYXNlID0gc2VnbWVudHMgKiBwb2ludHMubGVuZ3RoICogMztcblxuXHRcdGZvciAoIGkgPSAwLCBqID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkgKyssIGogKz0gMyApIHtcblxuXHRcdFx0Ly8gc2VsZWN0IHRoZSBub3JtYWwgb2YgdGhlIHZlcnRleCBpbiB0aGUgZmlyc3QgbGluZVxuXG5cdFx0XHRuMS54ID0gbm9ybWFsc1sgaiArIDAgXTtcblx0XHRcdG4xLnkgPSBub3JtYWxzWyBqICsgMSBdO1xuXHRcdFx0bjEueiA9IG5vcm1hbHNbIGogKyAyIF07XG5cblx0XHRcdC8vIHNlbGVjdCB0aGUgbm9ybWFsIG9mIHRoZSB2ZXJ0ZXggaW4gdGhlIGxhc3QgbGluZVxuXG5cdFx0XHRuMi54ID0gbm9ybWFsc1sgYmFzZSArIGogKyAwIF07XG5cdFx0XHRuMi55ID0gbm9ybWFsc1sgYmFzZSArIGogKyAxIF07XG5cdFx0XHRuMi56ID0gbm9ybWFsc1sgYmFzZSArIGogKyAyIF07XG5cblx0XHRcdC8vIGF2ZXJhZ2Ugbm9ybWFsc1xuXG5cdFx0XHRuLmFkZFZlY3RvcnMoIG4xLCBuMiApLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHQvLyBhc3NpZ24gdGhlIG5ldyB2YWx1ZXMgdG8gYm90aCBub3JtYWxzXG5cblx0XHRcdG5vcm1hbHNbIGogKyAwIF0gPSBub3JtYWxzWyBiYXNlICsgaiArIDAgXSA9IG4ueDtcblx0XHRcdG5vcm1hbHNbIGogKyAxIF0gPSBub3JtYWxzWyBiYXNlICsgaiArIDEgXSA9IG4ueTtcblx0XHRcdG5vcm1hbHNbIGogKyAyIF0gPSBub3JtYWxzWyBiYXNlICsgaiArIDIgXSA9IG4uejtcblxuXHRcdH1cblxuXHR9XG5cbn1cblxuTGF0aGVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcbkxhdGhlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF0aGVCdWZmZXJHZW9tZXRyeTtcblxuLyoqXG4gKiBAYXV0aG9yIGpvbm9icjEgLyBodHRwOi8vam9ub2JyMS5jb21cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gU2hhcGVHZW9tZXRyeVxuXG5mdW5jdGlvbiBTaGFwZUdlb21ldHJ5KCBzaGFwZXMsIGN1cnZlU2VnbWVudHMgKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdTaGFwZUdlb21ldHJ5JztcblxuXHRpZiAoIHR5cGVvZiBjdXJ2ZVNlZ21lbnRzID09PSAnb2JqZWN0JyApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlNoYXBlR2VvbWV0cnk6IE9wdGlvbnMgcGFyYW1ldGVyIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdFx0Y3VydmVTZWdtZW50cyA9IGN1cnZlU2VnbWVudHMuY3VydmVTZWdtZW50cztcblxuXHR9XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHNoYXBlczogc2hhcGVzLFxuXHRcdGN1cnZlU2VnbWVudHM6IGN1cnZlU2VnbWVudHNcblx0fTtcblxuXHR0aGlzLmZyb21CdWZmZXJHZW9tZXRyeSggbmV3IFNoYXBlQnVmZmVyR2VvbWV0cnkoIHNoYXBlcywgY3VydmVTZWdtZW50cyApICk7XG5cdHRoaXMubWVyZ2VWZXJ0aWNlcygpO1xuXG59XG5cblNoYXBlR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5TaGFwZUdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFNoYXBlR2VvbWV0cnk7XG5cbi8vIFNoYXBlQnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gU2hhcGVCdWZmZXJHZW9tZXRyeSggc2hhcGVzLCBjdXJ2ZVNlZ21lbnRzICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnU2hhcGVCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHNoYXBlczogc2hhcGVzLFxuXHRcdGN1cnZlU2VnbWVudHM6IGN1cnZlU2VnbWVudHNcblx0fTtcblxuXHRjdXJ2ZVNlZ21lbnRzID0gY3VydmVTZWdtZW50cyB8fCAxMjtcblxuXHQvLyBidWZmZXJzXG5cblx0dmFyIGluZGljZXMgPSBbXTtcblx0dmFyIHZlcnRpY2VzID0gW107XG5cdHZhciBub3JtYWxzID0gW107XG5cdHZhciB1dnMgPSBbXTtcblxuXHQvLyBoZWxwZXIgdmFyaWFibGVzXG5cblx0dmFyIGdyb3VwU3RhcnQgPSAwO1xuXHR2YXIgZ3JvdXBDb3VudCA9IDA7XG5cblx0Ly8gYWxsb3cgc2luZ2xlIGFuZCBhcnJheSB2YWx1ZXMgZm9yIFwic2hhcGVzXCIgcGFyYW1ldGVyXG5cblx0aWYgKCBBcnJheS5pc0FycmF5KCBzaGFwZXMgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRhZGRTaGFwZSggc2hhcGVzICk7XG5cblx0fSBlbHNlIHtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHNoYXBlcy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdGFkZFNoYXBlKCBzaGFwZXNbIGkgXSApO1xuXG5cdFx0XHR0aGlzLmFkZEdyb3VwKCBncm91cFN0YXJ0LCBncm91cENvdW50LCBpICk7IC8vIGVuYWJsZXMgTXVsdGlNYXRlcmlhbCBzdXBwb3J0XG5cblx0XHRcdGdyb3VwU3RhcnQgKz0gZ3JvdXBDb3VudDtcblx0XHRcdGdyb3VwQ291bnQgPSAwO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBidWlsZCBnZW9tZXRyeVxuXG5cdHRoaXMuc2V0SW5kZXgoIGluZGljZXMgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0aWNlcywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAnbm9ybWFsJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG5vcm1hbHMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHV2cywgMiApICk7XG5cblxuXHQvLyBoZWxwZXIgZnVuY3Rpb25zXG5cblx0ZnVuY3Rpb24gYWRkU2hhcGUoIHNoYXBlICkge1xuXG5cdFx0dmFyIGksIGwsIHNoYXBlSG9sZTtcblxuXHRcdHZhciBpbmRleE9mZnNldCA9IHZlcnRpY2VzLmxlbmd0aCAvIDM7XG5cdFx0dmFyIHBvaW50cyA9IHNoYXBlLmV4dHJhY3RQb2ludHMoIGN1cnZlU2VnbWVudHMgKTtcblxuXHRcdHZhciBzaGFwZVZlcnRpY2VzID0gcG9pbnRzLnNoYXBlO1xuXHRcdHZhciBzaGFwZUhvbGVzID0gcG9pbnRzLmhvbGVzO1xuXG5cdFx0Ly8gY2hlY2sgZGlyZWN0aW9uIG9mIHZlcnRpY2VzXG5cblx0XHRpZiAoIFNoYXBlVXRpbHMuaXNDbG9ja1dpc2UoIHNoYXBlVmVydGljZXMgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdHNoYXBlVmVydGljZXMgPSBzaGFwZVZlcnRpY2VzLnJldmVyc2UoKTtcblxuXHRcdFx0Ly8gYWxzbyBjaGVjayBpZiBob2xlcyBhcmUgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxuXG5cdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNoYXBlSG9sZXMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRzaGFwZUhvbGUgPSBzaGFwZUhvbGVzWyBpIF07XG5cblx0XHRcdFx0aWYgKCBTaGFwZVV0aWxzLmlzQ2xvY2tXaXNlKCBzaGFwZUhvbGUgKSA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdHNoYXBlSG9sZXNbIGkgXSA9IHNoYXBlSG9sZS5yZXZlcnNlKCk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHR2YXIgZmFjZXMgPSBTaGFwZVV0aWxzLnRyaWFuZ3VsYXRlU2hhcGUoIHNoYXBlVmVydGljZXMsIHNoYXBlSG9sZXMgKTtcblxuXHRcdC8vIGpvaW4gdmVydGljZXMgb2YgaW5uZXIgYW5kIG91dGVyIHBhdGhzIHRvIGEgc2luZ2xlIGFycmF5XG5cblx0XHRmb3IgKCBpID0gMCwgbCA9IHNoYXBlSG9sZXMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0c2hhcGVIb2xlID0gc2hhcGVIb2xlc1sgaSBdO1xuXHRcdFx0c2hhcGVWZXJ0aWNlcyA9IHNoYXBlVmVydGljZXMuY29uY2F0KCBzaGFwZUhvbGUgKTtcblxuXHRcdH1cblxuXHRcdC8vIHZlcnRpY2VzLCBub3JtYWxzLCB1dnNcblxuXHRcdGZvciAoIGkgPSAwLCBsID0gc2hhcGVWZXJ0aWNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgdmVydGV4ID0gc2hhcGVWZXJ0aWNlc1sgaSBdO1xuXG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIDAgKTtcblx0XHRcdG5vcm1hbHMucHVzaCggMCwgMCwgMSApO1xuXHRcdFx0dXZzLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSApOyAvLyB3b3JsZCB1dnNcblxuXHRcdH1cblxuXHRcdC8vIGluY2lkZXNcblxuXHRcdGZvciAoIGkgPSAwLCBsID0gZmFjZXMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGZhY2UgPSBmYWNlc1sgaSBdO1xuXG5cdFx0XHR2YXIgYSA9IGZhY2VbIDAgXSArIGluZGV4T2Zmc2V0O1xuXHRcdFx0dmFyIGIgPSBmYWNlWyAxIF0gKyBpbmRleE9mZnNldDtcblx0XHRcdHZhciBjID0gZmFjZVsgMiBdICsgaW5kZXhPZmZzZXQ7XG5cblx0XHRcdGluZGljZXMucHVzaCggYSwgYiwgYyApO1xuXHRcdFx0Z3JvdXBDb3VudCArPSAzO1xuXG5cdFx0fVxuXG5cdH1cblxufVxuXG5TaGFwZUJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZSApO1xuU2hhcGVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBTaGFwZUJ1ZmZlckdlb21ldHJ5O1xuXG4vKipcbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG5mdW5jdGlvbiBFZGdlc0dlb21ldHJ5KCBnZW9tZXRyeSwgdGhyZXNob2xkQW5nbGUgKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdFZGdlc0dlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0dGhyZXNob2xkQW5nbGU6IHRocmVzaG9sZEFuZ2xlXG5cdH07XG5cblx0dGhyZXNob2xkQW5nbGUgPSAoIHRocmVzaG9sZEFuZ2xlICE9PSB1bmRlZmluZWQgKSA/IHRocmVzaG9sZEFuZ2xlIDogMTtcblxuXHQvLyBidWZmZXJcblxuXHR2YXIgdmVydGljZXMgPSBbXTtcblxuXHQvLyBoZWxwZXIgdmFyaWFibGVzXG5cblx0dmFyIHRocmVzaG9sZERvdCA9IE1hdGguY29zKCBfTWF0aC5ERUcyUkFEICogdGhyZXNob2xkQW5nbGUgKTtcblx0dmFyIGVkZ2UgPSBbIDAsIDAgXSwgZWRnZXMgPSB7fSwgZWRnZTEsIGVkZ2UyO1xuXHR2YXIga2V5LCBrZXlzID0gWyAnYScsICdiJywgJ2MnIF07XG5cblx0Ly8gcHJlcGFyZSBzb3VyY2UgZ2VvbWV0cnlcblxuXHR2YXIgZ2VvbWV0cnkyO1xuXG5cdGlmICggZ2VvbWV0cnkuaXNCdWZmZXJHZW9tZXRyeSApIHtcblxuXHRcdGdlb21ldHJ5MiA9IG5ldyBHZW9tZXRyeSgpO1xuXHRcdGdlb21ldHJ5Mi5mcm9tQnVmZmVyR2VvbWV0cnkoIGdlb21ldHJ5ICk7XG5cblx0fSBlbHNlIHtcblxuXHRcdGdlb21ldHJ5MiA9IGdlb21ldHJ5LmNsb25lKCk7XG5cblx0fVxuXG5cdGdlb21ldHJ5Mi5tZXJnZVZlcnRpY2VzKCk7XG5cdGdlb21ldHJ5Mi5jb21wdXRlRmFjZU5vcm1hbHMoKTtcblxuXHR2YXIgc291cmNlVmVydGljZXMgPSBnZW9tZXRyeTIudmVydGljZXM7XG5cdHZhciBmYWNlcyA9IGdlb21ldHJ5Mi5mYWNlcztcblxuXHQvLyBub3cgY3JlYXRlIGEgZGF0YSBzdHJ1Y3R1cmUgd2hlcmUgZWFjaCBlbnRyeSByZXByZXNlbnRzIGFuIGVkZ2Ugd2l0aCBpdHMgYWRqb2luaW5nIGZhY2VzXG5cblx0Zm9yICggdmFyIGkgPSAwLCBsID0gZmFjZXMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdHZhciBmYWNlID0gZmFjZXNbIGkgXTtcblxuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IDM7IGogKysgKSB7XG5cblx0XHRcdGVkZ2UxID0gZmFjZVsga2V5c1sgaiBdIF07XG5cdFx0XHRlZGdlMiA9IGZhY2VbIGtleXNbICggaiArIDEgKSAlIDMgXSBdO1xuXHRcdFx0ZWRnZVsgMCBdID0gTWF0aC5taW4oIGVkZ2UxLCBlZGdlMiApO1xuXHRcdFx0ZWRnZVsgMSBdID0gTWF0aC5tYXgoIGVkZ2UxLCBlZGdlMiApO1xuXG5cdFx0XHRrZXkgPSBlZGdlWyAwIF0gKyAnLCcgKyBlZGdlWyAxIF07XG5cblx0XHRcdGlmICggZWRnZXNbIGtleSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0ZWRnZXNbIGtleSBdID0geyBpbmRleDE6IGVkZ2VbIDAgXSwgaW5kZXgyOiBlZGdlWyAxIF0sIGZhY2UxOiBpLCBmYWNlMjogdW5kZWZpbmVkIH07XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0ZWRnZXNbIGtleSBdLmZhY2UyID0gaTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBnZW5lcmF0ZSB2ZXJ0aWNlc1xuXG5cdGZvciAoIGtleSBpbiBlZGdlcyApIHtcblxuXHRcdHZhciBlID0gZWRnZXNbIGtleSBdO1xuXG5cdFx0Ly8gYW4gZWRnZSBpcyBvbmx5IHJlbmRlcmVkIGlmIHRoZSBhbmdsZSAoaW4gZGVncmVlcykgYmV0d2VlbiB0aGUgZmFjZSBub3JtYWxzIG9mIHRoZSBhZGpvaW5pbmcgZmFjZXMgZXhjZWVkcyB0aGlzIHZhbHVlLiBkZWZhdWx0ID0gMSBkZWdyZWUuXG5cblx0XHRpZiAoIGUuZmFjZTIgPT09IHVuZGVmaW5lZCB8fCBmYWNlc1sgZS5mYWNlMSBdLm5vcm1hbC5kb3QoIGZhY2VzWyBlLmZhY2UyIF0ubm9ybWFsICkgPD0gdGhyZXNob2xkRG90ICkge1xuXG5cdFx0XHR2YXIgdmVydGV4ID0gc291cmNlVmVydGljZXNbIGUuaW5kZXgxIF07XG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCB2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56ICk7XG5cblx0XHRcdHZlcnRleCA9IHNvdXJjZVZlcnRpY2VzWyBlLmluZGV4MiBdO1xuXHRcdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHQvLyBidWlsZCBnZW9tZXRyeVxuXG5cdHRoaXMuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXG59XG5cbkVkZ2VzR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5FZGdlc0dlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEVkZ2VzR2VvbWV0cnk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKi9cblxuLy8gQ3lsaW5kZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBDeWxpbmRlckdlb21ldHJ5KCByYWRpdXNUb3AsIHJhZGl1c0JvdHRvbSwgaGVpZ2h0LCByYWRpYWxTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIG9wZW5FbmRlZCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdDeWxpbmRlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzVG9wOiByYWRpdXNUb3AsXG5cdFx0cmFkaXVzQm90dG9tOiByYWRpdXNCb3R0b20sXG5cdFx0aGVpZ2h0OiBoZWlnaHQsXG5cdFx0cmFkaWFsU2VnbWVudHM6IHJhZGlhbFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50cyxcblx0XHRvcGVuRW5kZWQ6IG9wZW5FbmRlZCxcblx0XHR0aGV0YVN0YXJ0OiB0aGV0YVN0YXJ0LFxuXHRcdHRoZXRhTGVuZ3RoOiB0aGV0YUxlbmd0aFxuXHR9O1xuXG5cdHRoaXMuZnJvbUJ1ZmZlckdlb21ldHJ5KCBuZXcgQ3lsaW5kZXJCdWZmZXJHZW9tZXRyeSggcmFkaXVzVG9wLCByYWRpdXNCb3R0b20sIGhlaWdodCwgcmFkaWFsU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCBvcGVuRW5kZWQsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuQ3lsaW5kZXJHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBHZW9tZXRyeS5wcm90b3R5cGUgKTtcbkN5bGluZGVyR2VvbWV0cnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ3lsaW5kZXJHZW9tZXRyeTtcblxuLy8gQ3lsaW5kZXJCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBDeWxpbmRlckJ1ZmZlckdlb21ldHJ5KCByYWRpdXNUb3AsIHJhZGl1c0JvdHRvbSwgaGVpZ2h0LCByYWRpYWxTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIG9wZW5FbmRlZCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0QnVmZmVyR2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdDeWxpbmRlckJ1ZmZlckdlb21ldHJ5JztcblxuXHR0aGlzLnBhcmFtZXRlcnMgPSB7XG5cdFx0cmFkaXVzVG9wOiByYWRpdXNUb3AsXG5cdFx0cmFkaXVzQm90dG9tOiByYWRpdXNCb3R0b20sXG5cdFx0aGVpZ2h0OiBoZWlnaHQsXG5cdFx0cmFkaWFsU2VnbWVudHM6IHJhZGlhbFNlZ21lbnRzLFxuXHRcdGhlaWdodFNlZ21lbnRzOiBoZWlnaHRTZWdtZW50cyxcblx0XHRvcGVuRW5kZWQ6IG9wZW5FbmRlZCxcblx0XHR0aGV0YVN0YXJ0OiB0aGV0YVN0YXJ0LFxuXHRcdHRoZXRhTGVuZ3RoOiB0aGV0YUxlbmd0aFxuXHR9O1xuXG5cdHZhciBzY29wZSA9IHRoaXM7XG5cblx0cmFkaXVzVG9wID0gcmFkaXVzVG9wICE9PSB1bmRlZmluZWQgPyByYWRpdXNUb3AgOiAyMDtcblx0cmFkaXVzQm90dG9tID0gcmFkaXVzQm90dG9tICE9PSB1bmRlZmluZWQgPyByYWRpdXNCb3R0b20gOiAyMDtcblx0aGVpZ2h0ID0gaGVpZ2h0ICE9PSB1bmRlZmluZWQgPyBoZWlnaHQgOiAxMDA7XG5cblx0cmFkaWFsU2VnbWVudHMgPSBNYXRoLmZsb29yKCByYWRpYWxTZWdtZW50cyApIHx8IDg7XG5cdGhlaWdodFNlZ21lbnRzID0gTWF0aC5mbG9vciggaGVpZ2h0U2VnbWVudHMgKSB8fCAxO1xuXG5cdG9wZW5FbmRlZCA9IG9wZW5FbmRlZCAhPT0gdW5kZWZpbmVkID8gb3BlbkVuZGVkIDogZmFsc2U7XG5cdHRoZXRhU3RhcnQgPSB0aGV0YVN0YXJ0ICE9PSB1bmRlZmluZWQgPyB0aGV0YVN0YXJ0IDogMC4wO1xuXHR0aGV0YUxlbmd0aCA9IHRoZXRhTGVuZ3RoICE9PSB1bmRlZmluZWQgPyB0aGV0YUxlbmd0aCA6IDIuMCAqIE1hdGguUEk7XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0Ly8gaGVscGVyIHZhcmlhYmxlc1xuXG5cdHZhciBpbmRleCA9IDA7XG5cdHZhciBpbmRleEFycmF5ID0gW107XG5cdHZhciBoYWxmSGVpZ2h0ID0gaGVpZ2h0IC8gMjtcblx0dmFyIGdyb3VwU3RhcnQgPSAwO1xuXG5cdC8vIGdlbmVyYXRlIGdlb21ldHJ5XG5cblx0Z2VuZXJhdGVUb3JzbygpO1xuXG5cdGlmICggb3BlbkVuZGVkID09PSBmYWxzZSApIHtcblxuXHRcdGlmICggcmFkaXVzVG9wID4gMCApIGdlbmVyYXRlQ2FwKCB0cnVlICk7XG5cdFx0aWYgKCByYWRpdXNCb3R0b20gPiAwICkgZ2VuZXJhdGVDYXAoIGZhbHNlICk7XG5cblx0fVxuXG5cdC8vIGJ1aWxkIGdlb21ldHJ5XG5cblx0dGhpcy5zZXRJbmRleCggaW5kaWNlcyApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdub3JtYWwnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggbm9ybWFscywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAndXYnLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdXZzLCAyICkgKTtcblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVRvcnNvKCkge1xuXG5cdFx0dmFyIHgsIHk7XG5cdFx0dmFyIG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIHZlcnRleCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHR2YXIgZ3JvdXBDb3VudCA9IDA7XG5cblx0XHQvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBjYWxjdWxhdGUgdGhlIG5vcm1hbFxuXHRcdHZhciBzbG9wZSA9ICggcmFkaXVzQm90dG9tIC0gcmFkaXVzVG9wICkgLyBoZWlnaHQ7XG5cblx0XHQvLyBnZW5lcmF0ZSB2ZXJ0aWNlcywgbm9ybWFscyBhbmQgdXZzXG5cblx0XHRmb3IgKCB5ID0gMDsgeSA8PSBoZWlnaHRTZWdtZW50czsgeSArKyApIHtcblxuXHRcdFx0dmFyIGluZGV4Um93ID0gW107XG5cblx0XHRcdHZhciB2ID0geSAvIGhlaWdodFNlZ21lbnRzO1xuXG5cdFx0XHQvLyBjYWxjdWxhdGUgdGhlIHJhZGl1cyBvZiB0aGUgY3VycmVudCByb3dcblxuXHRcdFx0dmFyIHJhZGl1cyA9IHYgKiAoIHJhZGl1c0JvdHRvbSAtIHJhZGl1c1RvcCApICsgcmFkaXVzVG9wO1xuXG5cdFx0XHRmb3IgKCB4ID0gMDsgeCA8PSByYWRpYWxTZWdtZW50czsgeCArKyApIHtcblxuXHRcdFx0XHR2YXIgdSA9IHggLyByYWRpYWxTZWdtZW50cztcblxuXHRcdFx0XHR2YXIgdGhldGEgPSB1ICogdGhldGFMZW5ndGggKyB0aGV0YVN0YXJ0O1xuXG5cdFx0XHRcdHZhciBzaW5UaGV0YSA9IE1hdGguc2luKCB0aGV0YSApO1xuXHRcdFx0XHR2YXIgY29zVGhldGEgPSBNYXRoLmNvcyggdGhldGEgKTtcblxuXHRcdFx0XHQvLyB2ZXJ0ZXhcblxuXHRcdFx0XHR2ZXJ0ZXgueCA9IHJhZGl1cyAqIHNpblRoZXRhO1xuXHRcdFx0XHR2ZXJ0ZXgueSA9IC0gdiAqIGhlaWdodCArIGhhbGZIZWlnaHQ7XG5cdFx0XHRcdHZlcnRleC56ID0gcmFkaXVzICogY29zVGhldGE7XG5cdFx0XHRcdHZlcnRpY2VzLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKTtcblxuXHRcdFx0XHQvLyBub3JtYWxcblxuXHRcdFx0XHRub3JtYWwuc2V0KCBzaW5UaGV0YSwgc2xvcGUsIGNvc1RoZXRhICkubm9ybWFsaXplKCk7XG5cdFx0XHRcdG5vcm1hbHMucHVzaCggbm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiApO1xuXG5cdFx0XHRcdC8vIHV2XG5cblx0XHRcdFx0dXZzLnB1c2goIHUsIDEgLSB2ICk7XG5cblx0XHRcdFx0Ly8gc2F2ZSBpbmRleCBvZiB2ZXJ0ZXggaW4gcmVzcGVjdGl2ZSByb3dcblxuXHRcdFx0XHRpbmRleFJvdy5wdXNoKCBpbmRleCArKyApO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIG5vdyBzYXZlIHZlcnRpY2VzIG9mIHRoZSByb3cgaW4gb3VyIGluZGV4IGFycmF5XG5cblx0XHRcdGluZGV4QXJyYXkucHVzaCggaW5kZXhSb3cgKTtcblxuXHRcdH1cblxuXHRcdC8vIGdlbmVyYXRlIGluZGljZXNcblxuXHRcdGZvciAoIHggPSAwOyB4IDwgcmFkaWFsU2VnbWVudHM7IHggKysgKSB7XG5cblx0XHRcdGZvciAoIHkgPSAwOyB5IDwgaGVpZ2h0U2VnbWVudHM7IHkgKysgKSB7XG5cblx0XHRcdFx0Ly8gd2UgdXNlIHRoZSBpbmRleCBhcnJheSB0byBhY2Nlc3MgdGhlIGNvcnJlY3QgaW5kaWNlc1xuXG5cdFx0XHRcdHZhciBhID0gaW5kZXhBcnJheVsgeSBdWyB4IF07XG5cdFx0XHRcdHZhciBiID0gaW5kZXhBcnJheVsgeSArIDEgXVsgeCBdO1xuXHRcdFx0XHR2YXIgYyA9IGluZGV4QXJyYXlbIHkgKyAxIF1bIHggKyAxIF07XG5cdFx0XHRcdHZhciBkID0gaW5kZXhBcnJheVsgeSBdWyB4ICsgMSBdO1xuXG5cdFx0XHRcdC8vIGZhY2VzXG5cblx0XHRcdFx0aW5kaWNlcy5wdXNoKCBhLCBiLCBkICk7XG5cdFx0XHRcdGluZGljZXMucHVzaCggYiwgYywgZCApO1xuXG5cdFx0XHRcdC8vIHVwZGF0ZSBncm91cCBjb3VudGVyXG5cblx0XHRcdFx0Z3JvdXBDb3VudCArPSA2O1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHQvLyBhZGQgYSBncm91cCB0byB0aGUgZ2VvbWV0cnkuIHRoaXMgd2lsbCBlbnN1cmUgbXVsdGkgbWF0ZXJpYWwgc3VwcG9ydFxuXG5cdFx0c2NvcGUuYWRkR3JvdXAoIGdyb3VwU3RhcnQsIGdyb3VwQ291bnQsIDAgKTtcblxuXHRcdC8vIGNhbGN1bGF0ZSBuZXcgc3RhcnQgdmFsdWUgZm9yIGdyb3Vwc1xuXG5cdFx0Z3JvdXBTdGFydCArPSBncm91cENvdW50O1xuXG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZUNhcCggdG9wICkge1xuXG5cdFx0dmFyIHgsIGNlbnRlckluZGV4U3RhcnQsIGNlbnRlckluZGV4RW5kO1xuXG5cdFx0dmFyIHV2ID0gbmV3IFZlY3RvcjIoKTtcblx0XHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHZhciBncm91cENvdW50ID0gMDtcblxuXHRcdHZhciByYWRpdXMgPSAoIHRvcCA9PT0gdHJ1ZSApID8gcmFkaXVzVG9wIDogcmFkaXVzQm90dG9tO1xuXHRcdHZhciBzaWduID0gKCB0b3AgPT09IHRydWUgKSA/IDEgOiAtIDE7XG5cblx0XHQvLyBzYXZlIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgY2VudGVyIHZlcnRleFxuXHRcdGNlbnRlckluZGV4U3RhcnQgPSBpbmRleDtcblxuXHRcdC8vIGZpcnN0IHdlIGdlbmVyYXRlIHRoZSBjZW50ZXIgdmVydGV4IGRhdGEgb2YgdGhlIGNhcC5cblx0XHQvLyBiZWNhdXNlIHRoZSBnZW9tZXRyeSBuZWVkcyBvbmUgc2V0IG9mIHV2cyBwZXIgZmFjZSxcblx0XHQvLyB3ZSBtdXN0IGdlbmVyYXRlIGEgY2VudGVyIHZlcnRleCBwZXIgZmFjZS9zZWdtZW50XG5cblx0XHRmb3IgKCB4ID0gMTsgeCA8PSByYWRpYWxTZWdtZW50czsgeCArKyApIHtcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHZlcnRpY2VzLnB1c2goIDAsIGhhbGZIZWlnaHQgKiBzaWduLCAwICk7XG5cblx0XHRcdC8vIG5vcm1hbFxuXG5cdFx0XHRub3JtYWxzLnB1c2goIDAsIHNpZ24sIDAgKTtcblxuXHRcdFx0Ly8gdXZcblxuXHRcdFx0dXZzLnB1c2goIDAuNSwgMC41ICk7XG5cblx0XHRcdC8vIGluY3JlYXNlIGluZGV4XG5cblx0XHRcdGluZGV4ICsrO1xuXG5cdFx0fVxuXG5cdFx0Ly8gc2F2ZSB0aGUgaW5kZXggb2YgdGhlIGxhc3QgY2VudGVyIHZlcnRleFxuXG5cdFx0Y2VudGVySW5kZXhFbmQgPSBpbmRleDtcblxuXHRcdC8vIG5vdyB3ZSBnZW5lcmF0ZSB0aGUgc3Vycm91bmRpbmcgdmVydGljZXMsIG5vcm1hbHMgYW5kIHV2c1xuXG5cdFx0Zm9yICggeCA9IDA7IHggPD0gcmFkaWFsU2VnbWVudHM7IHggKysgKSB7XG5cblx0XHRcdHZhciB1ID0geCAvIHJhZGlhbFNlZ21lbnRzO1xuXHRcdFx0dmFyIHRoZXRhID0gdSAqIHRoZXRhTGVuZ3RoICsgdGhldGFTdGFydDtcblxuXHRcdFx0dmFyIGNvc1RoZXRhID0gTWF0aC5jb3MoIHRoZXRhICk7XG5cdFx0XHR2YXIgc2luVGhldGEgPSBNYXRoLnNpbiggdGhldGEgKTtcblxuXHRcdFx0Ly8gdmVydGV4XG5cblx0XHRcdHZlcnRleC54ID0gcmFkaXVzICogc2luVGhldGE7XG5cdFx0XHR2ZXJ0ZXgueSA9IGhhbGZIZWlnaHQgKiBzaWduO1xuXHRcdFx0dmVydGV4LnogPSByYWRpdXMgKiBjb3NUaGV0YTtcblx0XHRcdHZlcnRpY2VzLnB1c2goIHZlcnRleC54LCB2ZXJ0ZXgueSwgdmVydGV4LnogKTtcblxuXHRcdFx0Ly8gbm9ybWFsXG5cblx0XHRcdG5vcm1hbHMucHVzaCggMCwgc2lnbiwgMCApO1xuXG5cdFx0XHQvLyB1dlxuXG5cdFx0XHR1di54ID0gKCBjb3NUaGV0YSAqIDAuNSApICsgMC41O1xuXHRcdFx0dXYueSA9ICggc2luVGhldGEgKiAwLjUgKiBzaWduICkgKyAwLjU7XG5cdFx0XHR1dnMucHVzaCggdXYueCwgdXYueSApO1xuXG5cdFx0XHQvLyBpbmNyZWFzZSBpbmRleFxuXG5cdFx0XHRpbmRleCArKztcblxuXHRcdH1cblxuXHRcdC8vIGdlbmVyYXRlIGluZGljZXNcblxuXHRcdGZvciAoIHggPSAwOyB4IDwgcmFkaWFsU2VnbWVudHM7IHggKysgKSB7XG5cblx0XHRcdHZhciBjID0gY2VudGVySW5kZXhTdGFydCArIHg7XG5cdFx0XHR2YXIgaSA9IGNlbnRlckluZGV4RW5kICsgeDtcblxuXHRcdFx0aWYgKCB0b3AgPT09IHRydWUgKSB7XG5cblx0XHRcdFx0Ly8gZmFjZSB0b3BcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGksIGkgKyAxLCBjICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gZmFjZSBib3R0b21cblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goIGkgKyAxLCBpLCBjICk7XG5cblx0XHRcdH1cblxuXHRcdFx0Z3JvdXBDb3VudCArPSAzO1xuXG5cdFx0fVxuXG5cdFx0Ly8gYWRkIGEgZ3JvdXAgdG8gdGhlIGdlb21ldHJ5LiB0aGlzIHdpbGwgZW5zdXJlIG11bHRpIG1hdGVyaWFsIHN1cHBvcnRcblxuXHRcdHNjb3BlLmFkZEdyb3VwKCBncm91cFN0YXJ0LCBncm91cENvdW50LCB0b3AgPT09IHRydWUgPyAxIDogMiApO1xuXG5cdFx0Ly8gY2FsY3VsYXRlIG5ldyBzdGFydCB2YWx1ZSBmb3IgZ3JvdXBzXG5cblx0XHRncm91cFN0YXJ0ICs9IGdyb3VwQ291bnQ7XG5cblx0fVxuXG59XG5cbkN5bGluZGVyQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5DeWxpbmRlckJ1ZmZlckdlb21ldHJ5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEN5bGluZGVyQnVmZmVyR2VvbWV0cnk7XG5cbi8qKlxuICogQGF1dGhvciBhYmVsbmF0aW9uIC8gaHR0cDovL2dpdGh1Yi5jb20vYWJlbG5hdGlvblxuICovXG5cbi8vIENvbmVHZW9tZXRyeVxuXG5mdW5jdGlvbiBDb25lR2VvbWV0cnkoIHJhZGl1cywgaGVpZ2h0LCByYWRpYWxTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIG9wZW5FbmRlZCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0Q3lsaW5kZXJHZW9tZXRyeS5jYWxsKCB0aGlzLCAwLCByYWRpdXMsIGhlaWdodCwgcmFkaWFsU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCBvcGVuRW5kZWQsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICk7XG5cblx0dGhpcy50eXBlID0gJ0NvbmVHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdHJhZGlhbFNlZ21lbnRzOiByYWRpYWxTZWdtZW50cyxcblx0XHRoZWlnaHRTZWdtZW50czogaGVpZ2h0U2VnbWVudHMsXG5cdFx0b3BlbkVuZGVkOiBvcGVuRW5kZWQsXG5cdFx0dGhldGFTdGFydDogdGhldGFTdGFydCxcblx0XHR0aGV0YUxlbmd0aDogdGhldGFMZW5ndGhcblx0fTtcblxufVxuXG5Db25lR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQ3lsaW5kZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcbkNvbmVHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb25lR2VvbWV0cnk7XG5cbi8vIENvbmVCdWZmZXJHZW9tZXRyeVxuXG5mdW5jdGlvbiBDb25lQnVmZmVyR2VvbWV0cnkoIHJhZGl1cywgaGVpZ2h0LCByYWRpYWxTZWdtZW50cywgaGVpZ2h0U2VnbWVudHMsIG9wZW5FbmRlZCwgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0Q3lsaW5kZXJCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzLCAwLCByYWRpdXMsIGhlaWdodCwgcmFkaWFsU2VnbWVudHMsIGhlaWdodFNlZ21lbnRzLCBvcGVuRW5kZWQsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICk7XG5cblx0dGhpcy50eXBlID0gJ0NvbmVCdWZmZXJHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdHJhZGlhbFNlZ21lbnRzOiByYWRpYWxTZWdtZW50cyxcblx0XHRoZWlnaHRTZWdtZW50czogaGVpZ2h0U2VnbWVudHMsXG5cdFx0b3BlbkVuZGVkOiBvcGVuRW5kZWQsXG5cdFx0dGhldGFTdGFydDogdGhldGFTdGFydCxcblx0XHR0aGV0YUxlbmd0aDogdGhldGFMZW5ndGhcblx0fTtcblxufVxuXG5Db25lQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQ3lsaW5kZXJCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKTtcbkNvbmVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDb25lQnVmZmVyR2VvbWV0cnk7XG5cbi8qKlxuICogQGF1dGhvciBiZW5hYWRhbXMgLyBodHRwczovL3R3aXR0ZXIuY29tL2Jlbl9hX2FkYW1zXG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICogQGF1dGhvciBodWdoZXNcbiAqL1xuXG4vLyBDaXJjbGVHZW9tZXRyeVxuXG5mdW5jdGlvbiBDaXJjbGVHZW9tZXRyeSggcmFkaXVzLCBzZWdtZW50cywgdGhldGFTdGFydCwgdGhldGFMZW5ndGggKSB7XG5cblx0R2VvbWV0cnkuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdDaXJjbGVHZW9tZXRyeSc7XG5cblx0dGhpcy5wYXJhbWV0ZXJzID0ge1xuXHRcdHJhZGl1czogcmFkaXVzLFxuXHRcdHNlZ21lbnRzOiBzZWdtZW50cyxcblx0XHR0aGV0YVN0YXJ0OiB0aGV0YVN0YXJ0LFxuXHRcdHRoZXRhTGVuZ3RoOiB0aGV0YUxlbmd0aFxuXHR9O1xuXG5cdHRoaXMuZnJvbUJ1ZmZlckdlb21ldHJ5KCBuZXcgQ2lyY2xlQnVmZmVyR2VvbWV0cnkoIHJhZGl1cywgc2VnbWVudHMsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICkgKTtcblx0dGhpcy5tZXJnZVZlcnRpY2VzKCk7XG5cbn1cblxuQ2lyY2xlR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggR2VvbWV0cnkucHJvdG90eXBlICk7XG5DaXJjbGVHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDaXJjbGVHZW9tZXRyeTtcblxuLy8gQ2lyY2xlQnVmZmVyR2VvbWV0cnlcblxuZnVuY3Rpb24gQ2lyY2xlQnVmZmVyR2VvbWV0cnkoIHJhZGl1cywgc2VnbWVudHMsIHRoZXRhU3RhcnQsIHRoZXRhTGVuZ3RoICkge1xuXG5cdEJ1ZmZlckdlb21ldHJ5LmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnQ2lyY2xlQnVmZmVyR2VvbWV0cnknO1xuXG5cdHRoaXMucGFyYW1ldGVycyA9IHtcblx0XHRyYWRpdXM6IHJhZGl1cyxcblx0XHRzZWdtZW50czogc2VnbWVudHMsXG5cdFx0dGhldGFTdGFydDogdGhldGFTdGFydCxcblx0XHR0aGV0YUxlbmd0aDogdGhldGFMZW5ndGhcblx0fTtcblxuXHRyYWRpdXMgPSByYWRpdXMgfHwgNTA7XG5cdHNlZ21lbnRzID0gc2VnbWVudHMgIT09IHVuZGVmaW5lZCA/IE1hdGgubWF4KCAzLCBzZWdtZW50cyApIDogODtcblxuXHR0aGV0YVN0YXJ0ID0gdGhldGFTdGFydCAhPT0gdW5kZWZpbmVkID8gdGhldGFTdGFydCA6IDA7XG5cdHRoZXRhTGVuZ3RoID0gdGhldGFMZW5ndGggIT09IHVuZGVmaW5lZCA/IHRoZXRhTGVuZ3RoIDogTWF0aC5QSSAqIDI7XG5cblx0Ly8gYnVmZmVyc1xuXG5cdHZhciBpbmRpY2VzID0gW107XG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgbm9ybWFscyA9IFtdO1xuXHR2YXIgdXZzID0gW107XG5cblx0Ly8gaGVscGVyIHZhcmlhYmxlc1xuXG5cdHZhciBpLCBzO1xuXHR2YXIgdmVydGV4ID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIHV2ID0gbmV3IFZlY3RvcjIoKTtcblxuXHQvLyBjZW50ZXIgcG9pbnRcblxuXHR2ZXJ0aWNlcy5wdXNoKCAwLCAwLCAwICk7XG5cdG5vcm1hbHMucHVzaCggMCwgMCwgMSApO1xuXHR1dnMucHVzaCggMC41LCAwLjUgKTtcblxuXHRmb3IgKCBzID0gMCwgaSA9IDM7IHMgPD0gc2VnbWVudHM7IHMgKyssIGkgKz0gMyApIHtcblxuXHRcdHZhciBzZWdtZW50ID0gdGhldGFTdGFydCArIHMgLyBzZWdtZW50cyAqIHRoZXRhTGVuZ3RoO1xuXG5cdFx0Ly8gdmVydGV4XG5cblx0XHR2ZXJ0ZXgueCA9IHJhZGl1cyAqIE1hdGguY29zKCBzZWdtZW50ICk7XG5cdFx0dmVydGV4LnkgPSByYWRpdXMgKiBNYXRoLnNpbiggc2VnbWVudCApO1xuXG5cdFx0dmVydGljZXMucHVzaCggdmVydGV4LngsIHZlcnRleC55LCB2ZXJ0ZXgueiApO1xuXG5cdFx0Ly8gbm9ybWFsXG5cblx0XHRub3JtYWxzLnB1c2goIDAsIDAsIDEgKTtcblxuXHRcdC8vIHV2c1xuXG5cdFx0dXYueCA9ICggdmVydGljZXNbIGkgXSAvIHJhZGl1cyArIDEgKSAvIDI7XG5cdFx0dXYueSA9ICggdmVydGljZXNbIGkgKyAxIF0gLyByYWRpdXMgKyAxICkgLyAyO1xuXG5cdFx0dXZzLnB1c2goIHV2LngsIHV2LnkgKTtcblxuXHR9XG5cblx0Ly8gaW5kaWNlc1xuXG5cdGZvciAoIGkgPSAxOyBpIDw9IHNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0aW5kaWNlcy5wdXNoKCBpLCBpICsgMSwgMCApO1xuXG5cdH1cblxuXHQvLyBidWlsZCBnZW9tZXRyeVxuXG5cdHRoaXMuc2V0SW5kZXgoIGluZGljZXMgKTtcblx0dGhpcy5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCB2ZXJ0aWNlcywgMyApICk7XG5cdHRoaXMuYWRkQXR0cmlidXRlKCAnbm9ybWFsJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG5vcm1hbHMsIDMgKSApO1xuXHR0aGlzLmFkZEF0dHJpYnV0ZSggJ3V2JywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHV2cywgMiApICk7XG5cbn1cblxuQ2lyY2xlQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlICk7XG5DaXJjbGVCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBDaXJjbGVCdWZmZXJHZW9tZXRyeTtcblxuXG5cbnZhciBHZW9tZXRyaWVzID0gT2JqZWN0LmZyZWV6ZSh7XG5cdFdpcmVmcmFtZUdlb21ldHJ5OiBXaXJlZnJhbWVHZW9tZXRyeSxcblx0UGFyYW1ldHJpY0dlb21ldHJ5OiBQYXJhbWV0cmljR2VvbWV0cnksXG5cdFBhcmFtZXRyaWNCdWZmZXJHZW9tZXRyeTogUGFyYW1ldHJpY0J1ZmZlckdlb21ldHJ5LFxuXHRUZXRyYWhlZHJvbkdlb21ldHJ5OiBUZXRyYWhlZHJvbkdlb21ldHJ5LFxuXHRUZXRyYWhlZHJvbkJ1ZmZlckdlb21ldHJ5OiBUZXRyYWhlZHJvbkJ1ZmZlckdlb21ldHJ5LFxuXHRPY3RhaGVkcm9uR2VvbWV0cnk6IE9jdGFoZWRyb25HZW9tZXRyeSxcblx0T2N0YWhlZHJvbkJ1ZmZlckdlb21ldHJ5OiBPY3RhaGVkcm9uQnVmZmVyR2VvbWV0cnksXG5cdEljb3NhaGVkcm9uR2VvbWV0cnk6IEljb3NhaGVkcm9uR2VvbWV0cnksXG5cdEljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnk6IEljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnksXG5cdERvZGVjYWhlZHJvbkdlb21ldHJ5OiBEb2RlY2FoZWRyb25HZW9tZXRyeSxcblx0RG9kZWNhaGVkcm9uQnVmZmVyR2VvbWV0cnk6IERvZGVjYWhlZHJvbkJ1ZmZlckdlb21ldHJ5LFxuXHRQb2x5aGVkcm9uR2VvbWV0cnk6IFBvbHloZWRyb25HZW9tZXRyeSxcblx0UG9seWhlZHJvbkJ1ZmZlckdlb21ldHJ5OiBQb2x5aGVkcm9uQnVmZmVyR2VvbWV0cnksXG5cdFR1YmVHZW9tZXRyeTogVHViZUdlb21ldHJ5LFxuXHRUdWJlQnVmZmVyR2VvbWV0cnk6IFR1YmVCdWZmZXJHZW9tZXRyeSxcblx0VG9ydXNLbm90R2VvbWV0cnk6IFRvcnVzS25vdEdlb21ldHJ5LFxuXHRUb3J1c0tub3RCdWZmZXJHZW9tZXRyeTogVG9ydXNLbm90QnVmZmVyR2VvbWV0cnksXG5cdFRvcnVzR2VvbWV0cnk6IFRvcnVzR2VvbWV0cnksXG5cdFRvcnVzQnVmZmVyR2VvbWV0cnk6IFRvcnVzQnVmZmVyR2VvbWV0cnksXG5cdFRleHRHZW9tZXRyeTogVGV4dEdlb21ldHJ5LFxuXHRUZXh0QnVmZmVyR2VvbWV0cnk6IFRleHRCdWZmZXJHZW9tZXRyeSxcblx0U3BoZXJlR2VvbWV0cnk6IFNwaGVyZUdlb21ldHJ5LFxuXHRTcGhlcmVCdWZmZXJHZW9tZXRyeTogU3BoZXJlQnVmZmVyR2VvbWV0cnksXG5cdFJpbmdHZW9tZXRyeTogUmluZ0dlb21ldHJ5LFxuXHRSaW5nQnVmZmVyR2VvbWV0cnk6IFJpbmdCdWZmZXJHZW9tZXRyeSxcblx0UGxhbmVHZW9tZXRyeTogUGxhbmVHZW9tZXRyeSxcblx0UGxhbmVCdWZmZXJHZW9tZXRyeTogUGxhbmVCdWZmZXJHZW9tZXRyeSxcblx0TGF0aGVHZW9tZXRyeTogTGF0aGVHZW9tZXRyeSxcblx0TGF0aGVCdWZmZXJHZW9tZXRyeTogTGF0aGVCdWZmZXJHZW9tZXRyeSxcblx0U2hhcGVHZW9tZXRyeTogU2hhcGVHZW9tZXRyeSxcblx0U2hhcGVCdWZmZXJHZW9tZXRyeTogU2hhcGVCdWZmZXJHZW9tZXRyeSxcblx0RXh0cnVkZUdlb21ldHJ5OiBFeHRydWRlR2VvbWV0cnksXG5cdEV4dHJ1ZGVCdWZmZXJHZW9tZXRyeTogRXh0cnVkZUJ1ZmZlckdlb21ldHJ5LFxuXHRFZGdlc0dlb21ldHJ5OiBFZGdlc0dlb21ldHJ5LFxuXHRDb25lR2VvbWV0cnk6IENvbmVHZW9tZXRyeSxcblx0Q29uZUJ1ZmZlckdlb21ldHJ5OiBDb25lQnVmZmVyR2VvbWV0cnksXG5cdEN5bGluZGVyR2VvbWV0cnk6IEN5bGluZGVyR2VvbWV0cnksXG5cdEN5bGluZGVyQnVmZmVyR2VvbWV0cnk6IEN5bGluZGVyQnVmZmVyR2VvbWV0cnksXG5cdENpcmNsZUdlb21ldHJ5OiBDaXJjbGVHZW9tZXRyeSxcblx0Q2lyY2xlQnVmZmVyR2VvbWV0cnk6IENpcmNsZUJ1ZmZlckdlb21ldHJ5LFxuXHRCb3hHZW9tZXRyeTogQm94R2VvbWV0cnksXG5cdEJveEJ1ZmZlckdlb21ldHJ5OiBCb3hCdWZmZXJHZW9tZXRyeVxufSk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqXG4gKiBwYXJhbWV0ZXJzID0ge1xuICogIG9wYWNpdHk6IDxmbG9hdD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBTaGFkb3dNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRTaGFkZXJNYXRlcmlhbC5jYWxsKCB0aGlzLCB7XG5cdFx0dW5pZm9ybXM6IFVuaWZvcm1zVXRpbHMubWVyZ2UoIFtcblx0XHRcdFVuaWZvcm1zTGliLmxpZ2h0cyxcblx0XHRcdHtcblx0XHRcdFx0b3BhY2l0eTogeyB2YWx1ZTogMS4wIH1cblx0XHRcdH1cblx0XHRdICksXG5cdFx0dmVydGV4U2hhZGVyOiBTaGFkZXJDaHVua1sgJ3NoYWRvd192ZXJ0JyBdLFxuXHRcdGZyYWdtZW50U2hhZGVyOiBTaGFkZXJDaHVua1sgJ3NoYWRvd19mcmFnJyBdXG5cdH0gKTtcblxuXHR0aGlzLmxpZ2h0cyA9IHRydWU7XG5cdHRoaXMudHJhbnNwYXJlbnQgPSB0cnVlO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCB0aGlzLCB7XG5cdFx0b3BhY2l0eToge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdGdldDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy51bmlmb3Jtcy5vcGFjaXR5LnZhbHVlO1xuXHRcdFx0fSxcblx0XHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblx0XHRcdFx0dGhpcy51bmlmb3Jtcy5vcGFjaXR5LnZhbHVlID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG5cblx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5TaGFkb3dNYXRlcmlhbC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBTaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUgKTtcblNoYWRvd01hdGVyaWFsLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFNoYWRvd01hdGVyaWFsO1xuXG5TaGFkb3dNYXRlcmlhbC5wcm90b3R5cGUuaXNTaGFkb3dNYXRlcmlhbCA9IHRydWU7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBSYXdTaGFkZXJNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRTaGFkZXJNYXRlcmlhbC5jYWxsKCB0aGlzLCBwYXJhbWV0ZXJzICk7XG5cblx0dGhpcy50eXBlID0gJ1Jhd1NoYWRlck1hdGVyaWFsJztcblxufVxuXG5SYXdTaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBTaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUgKTtcblJhd1NoYWRlck1hdGVyaWFsLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFJhd1NoYWRlck1hdGVyaWFsO1xuXG5SYXdTaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUuaXNSYXdTaGFkZXJNYXRlcmlhbCA9IHRydWU7XG5cbi8qKlxuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBjb2xvcjogPGhleD4sXG4gKiAgcm91Z2huZXNzOiA8ZmxvYXQ+LFxuICogIG1ldGFsbmVzczogPGZsb2F0PixcbiAqICBvcGFjaXR5OiA8ZmxvYXQ+LFxuICpcbiAqICBtYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGxpZ2h0TWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGxpZ2h0TWFwSW50ZW5zaXR5OiA8ZmxvYXQ+XG4gKlxuICogIGFvTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGFvTWFwSW50ZW5zaXR5OiA8ZmxvYXQ+XG4gKlxuICogIGVtaXNzaXZlOiA8aGV4PixcbiAqICBlbWlzc2l2ZUludGVuc2l0eTogPGZsb2F0PlxuICogIGVtaXNzaXZlTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBidW1wTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGJ1bXBTY2FsZTogPGZsb2F0PixcbiAqXG4gKiAgbm9ybWFsTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIG5vcm1hbFNjYWxlOiA8VmVjdG9yMj4sXG4gKlxuICogIGRpc3BsYWNlbWVudE1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBkaXNwbGFjZW1lbnRTY2FsZTogPGZsb2F0PixcbiAqICBkaXNwbGFjZW1lbnRCaWFzOiA8ZmxvYXQ+LFxuICpcbiAqICByb3VnaG5lc3NNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIG1ldGFsbmVzc01hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKiAgYWxwaGFNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGVudk1hcDogbmV3IFRIUkVFLkN1YmVUZXh0dXJlKCBbcG9zeCwgbmVneCwgcG9zeSwgbmVneSwgcG9zeiwgbmVnel0gKSxcbiAqICBlbnZNYXBJbnRlbnNpdHk6IDxmbG9hdD5cbiAqXG4gKiAgcmVmcmFjdGlvblJhdGlvOiA8ZmxvYXQ+LFxuICpcbiAqICB3aXJlZnJhbWU6IDxib29sZWFuPixcbiAqICB3aXJlZnJhbWVMaW5ld2lkdGg6IDxmbG9hdD4sXG4gKlxuICogIHNraW5uaW5nOiA8Ym9vbD4sXG4gKiAgbW9ycGhUYXJnZXRzOiA8Ym9vbD4sXG4gKiAgbW9ycGhOb3JtYWxzOiA8Ym9vbD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBNZXNoU3RhbmRhcmRNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5kZWZpbmVzID0geyAnU1RBTkRBUkQnOiAnJyB9O1xuXG5cdHRoaXMudHlwZSA9ICdNZXNoU3RhbmRhcmRNYXRlcmlhbCc7XG5cblx0dGhpcy5jb2xvciA9IG5ldyBDb2xvciggMHhmZmZmZmYgKTsgLy8gZGlmZnVzZVxuXHR0aGlzLnJvdWdobmVzcyA9IDAuNTtcblx0dGhpcy5tZXRhbG5lc3MgPSAwLjU7XG5cblx0dGhpcy5tYXAgPSBudWxsO1xuXG5cdHRoaXMubGlnaHRNYXAgPSBudWxsO1xuXHR0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuYW9NYXAgPSBudWxsO1xuXHR0aGlzLmFvTWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuZW1pc3NpdmUgPSBuZXcgQ29sb3IoIDB4MDAwMDAwICk7XG5cdHRoaXMuZW1pc3NpdmVJbnRlbnNpdHkgPSAxLjA7XG5cdHRoaXMuZW1pc3NpdmVNYXAgPSBudWxsO1xuXG5cdHRoaXMuYnVtcE1hcCA9IG51bGw7XG5cdHRoaXMuYnVtcFNjYWxlID0gMTtcblxuXHR0aGlzLm5vcm1hbE1hcCA9IG51bGw7XG5cdHRoaXMubm9ybWFsU2NhbGUgPSBuZXcgVmVjdG9yMiggMSwgMSApO1xuXG5cdHRoaXMuZGlzcGxhY2VtZW50TWFwID0gbnVsbDtcblx0dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSA9IDE7XG5cdHRoaXMuZGlzcGxhY2VtZW50QmlhcyA9IDA7XG5cblx0dGhpcy5yb3VnaG5lc3NNYXAgPSBudWxsO1xuXG5cdHRoaXMubWV0YWxuZXNzTWFwID0gbnVsbDtcblxuXHR0aGlzLmFscGhhTWFwID0gbnVsbDtcblxuXHR0aGlzLmVudk1hcCA9IG51bGw7XG5cdHRoaXMuZW52TWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMucmVmcmFjdGlvblJhdGlvID0gMC45ODtcblxuXHR0aGlzLndpcmVmcmFtZSA9IGZhbHNlO1xuXHR0aGlzLndpcmVmcmFtZUxpbmV3aWR0aCA9IDE7XG5cdHRoaXMud2lyZWZyYW1lTGluZWNhcCA9ICdyb3VuZCc7XG5cdHRoaXMud2lyZWZyYW1lTGluZWpvaW4gPSAncm91bmQnO1xuXG5cdHRoaXMuc2tpbm5pbmcgPSBmYWxzZTtcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBmYWxzZTtcblx0dGhpcy5tb3JwaE5vcm1hbHMgPSBmYWxzZTtcblxuXHR0aGlzLnNldFZhbHVlcyggcGFyYW1ldGVycyApO1xuXG59XG5cbk1lc2hTdGFuZGFyZE1hdGVyaWFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE1hdGVyaWFsLnByb3RvdHlwZSApO1xuTWVzaFN0YW5kYXJkTWF0ZXJpYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTWVzaFN0YW5kYXJkTWF0ZXJpYWw7XG5cbk1lc2hTdGFuZGFyZE1hdGVyaWFsLnByb3RvdHlwZS5pc01lc2hTdGFuZGFyZE1hdGVyaWFsID0gdHJ1ZTtcblxuTWVzaFN0YW5kYXJkTWF0ZXJpYWwucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRNYXRlcmlhbC5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHR0aGlzLmRlZmluZXMgPSB7ICdTVEFOREFSRCc6ICcnIH07XG5cblx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblx0dGhpcy5yb3VnaG5lc3MgPSBzb3VyY2Uucm91Z2huZXNzO1xuXHR0aGlzLm1ldGFsbmVzcyA9IHNvdXJjZS5tZXRhbG5lc3M7XG5cblx0dGhpcy5tYXAgPSBzb3VyY2UubWFwO1xuXG5cdHRoaXMubGlnaHRNYXAgPSBzb3VyY2UubGlnaHRNYXA7XG5cdHRoaXMubGlnaHRNYXBJbnRlbnNpdHkgPSBzb3VyY2UubGlnaHRNYXBJbnRlbnNpdHk7XG5cblx0dGhpcy5hb01hcCA9IHNvdXJjZS5hb01hcDtcblx0dGhpcy5hb01hcEludGVuc2l0eSA9IHNvdXJjZS5hb01hcEludGVuc2l0eTtcblxuXHR0aGlzLmVtaXNzaXZlLmNvcHkoIHNvdXJjZS5lbWlzc2l2ZSApO1xuXHR0aGlzLmVtaXNzaXZlTWFwID0gc291cmNlLmVtaXNzaXZlTWFwO1xuXHR0aGlzLmVtaXNzaXZlSW50ZW5zaXR5ID0gc291cmNlLmVtaXNzaXZlSW50ZW5zaXR5O1xuXG5cdHRoaXMuYnVtcE1hcCA9IHNvdXJjZS5idW1wTWFwO1xuXHR0aGlzLmJ1bXBTY2FsZSA9IHNvdXJjZS5idW1wU2NhbGU7XG5cblx0dGhpcy5ub3JtYWxNYXAgPSBzb3VyY2Uubm9ybWFsTWFwO1xuXHR0aGlzLm5vcm1hbFNjYWxlLmNvcHkoIHNvdXJjZS5ub3JtYWxTY2FsZSApO1xuXG5cdHRoaXMuZGlzcGxhY2VtZW50TWFwID0gc291cmNlLmRpc3BsYWNlbWVudE1hcDtcblx0dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSA9IHNvdXJjZS5kaXNwbGFjZW1lbnRTY2FsZTtcblx0dGhpcy5kaXNwbGFjZW1lbnRCaWFzID0gc291cmNlLmRpc3BsYWNlbWVudEJpYXM7XG5cblx0dGhpcy5yb3VnaG5lc3NNYXAgPSBzb3VyY2Uucm91Z2huZXNzTWFwO1xuXG5cdHRoaXMubWV0YWxuZXNzTWFwID0gc291cmNlLm1ldGFsbmVzc01hcDtcblxuXHR0aGlzLmFscGhhTWFwID0gc291cmNlLmFscGhhTWFwO1xuXG5cdHRoaXMuZW52TWFwID0gc291cmNlLmVudk1hcDtcblx0dGhpcy5lbnZNYXBJbnRlbnNpdHkgPSBzb3VyY2UuZW52TWFwSW50ZW5zaXR5O1xuXG5cdHRoaXMucmVmcmFjdGlvblJhdGlvID0gc291cmNlLnJlZnJhY3Rpb25SYXRpbztcblxuXHR0aGlzLndpcmVmcmFtZSA9IHNvdXJjZS53aXJlZnJhbWU7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gc291cmNlLndpcmVmcmFtZUxpbmV3aWR0aDtcblx0dGhpcy53aXJlZnJhbWVMaW5lY2FwID0gc291cmNlLndpcmVmcmFtZUxpbmVjYXA7XG5cdHRoaXMud2lyZWZyYW1lTGluZWpvaW4gPSBzb3VyY2Uud2lyZWZyYW1lTGluZWpvaW47XG5cblx0dGhpcy5za2lubmluZyA9IHNvdXJjZS5za2lubmluZztcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXHR0aGlzLm1vcnBoTm9ybWFscyA9IHNvdXJjZS5tb3JwaE5vcm1hbHM7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICByZWZsZWN0aXZpdHk6IDxmbG9hdD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBNZXNoUGh5c2ljYWxNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNZXNoU3RhbmRhcmRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5kZWZpbmVzID0geyAnUEhZU0lDQUwnOiAnJyB9O1xuXG5cdHRoaXMudHlwZSA9ICdNZXNoUGh5c2ljYWxNYXRlcmlhbCc7XG5cblx0dGhpcy5yZWZsZWN0aXZpdHkgPSAwLjU7IC8vIG1hcHMgdG8gRjAgPSAwLjA0XG5cblx0dGhpcy5jbGVhckNvYXQgPSAwLjA7XG5cdHRoaXMuY2xlYXJDb2F0Um91Z2huZXNzID0gMC4wO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuTWVzaFBoeXNpY2FsTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWVzaFN0YW5kYXJkTWF0ZXJpYWwucHJvdG90eXBlICk7XG5NZXNoUGh5c2ljYWxNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBNZXNoUGh5c2ljYWxNYXRlcmlhbDtcblxuTWVzaFBoeXNpY2FsTWF0ZXJpYWwucHJvdG90eXBlLmlzTWVzaFBoeXNpY2FsTWF0ZXJpYWwgPSB0cnVlO1xuXG5NZXNoUGh5c2ljYWxNYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1lc2hTdGFuZGFyZE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuZGVmaW5lcyA9IHsgJ1BIWVNJQ0FMJzogJycgfTtcblxuXHR0aGlzLnJlZmxlY3Rpdml0eSA9IHNvdXJjZS5yZWZsZWN0aXZpdHk7XG5cblx0dGhpcy5jbGVhckNvYXQgPSBzb3VyY2UuY2xlYXJDb2F0O1xuXHR0aGlzLmNsZWFyQ29hdFJvdWdobmVzcyA9IHNvdXJjZS5jbGVhckNvYXRSb3VnaG5lc3M7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBjb2xvcjogPGhleD4sXG4gKiAgc3BlY3VsYXI6IDxoZXg+LFxuICogIHNoaW5pbmVzczogPGZsb2F0PixcbiAqICBvcGFjaXR5OiA8ZmxvYXQ+LFxuICpcbiAqICBtYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGxpZ2h0TWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGxpZ2h0TWFwSW50ZW5zaXR5OiA8ZmxvYXQ+XG4gKlxuICogIGFvTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGFvTWFwSW50ZW5zaXR5OiA8ZmxvYXQ+XG4gKlxuICogIGVtaXNzaXZlOiA8aGV4PixcbiAqICBlbWlzc2l2ZUludGVuc2l0eTogPGZsb2F0PlxuICogIGVtaXNzaXZlTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBidW1wTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIGJ1bXBTY2FsZTogPGZsb2F0PixcbiAqXG4gKiAgbm9ybWFsTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICogIG5vcm1hbFNjYWxlOiA8VmVjdG9yMj4sXG4gKlxuICogIGRpc3BsYWNlbWVudE1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBkaXNwbGFjZW1lbnRTY2FsZTogPGZsb2F0PixcbiAqICBkaXNwbGFjZW1lbnRCaWFzOiA8ZmxvYXQ+LFxuICpcbiAqICBzcGVjdWxhck1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKiAgYWxwaGFNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGVudk1hcDogbmV3IFRIUkVFLlRleHR1cmVDdWJlKCBbcG9zeCwgbmVneCwgcG9zeSwgbmVneSwgcG9zeiwgbmVnel0gKSxcbiAqICBjb21iaW5lOiBUSFJFRS5NdWx0aXBseSxcbiAqICByZWZsZWN0aXZpdHk6IDxmbG9hdD4sXG4gKiAgcmVmcmFjdGlvblJhdGlvOiA8ZmxvYXQ+LFxuICpcbiAqICB3aXJlZnJhbWU6IDxib29sZWFuPixcbiAqICB3aXJlZnJhbWVMaW5ld2lkdGg6IDxmbG9hdD4sXG4gKlxuICogIHNraW5uaW5nOiA8Ym9vbD4sXG4gKiAgbW9ycGhUYXJnZXRzOiA8Ym9vbD4sXG4gKiAgbW9ycGhOb3JtYWxzOiA8Ym9vbD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBNZXNoUGhvbmdNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ01lc2hQaG9uZ01hdGVyaWFsJztcblxuXHR0aGlzLmNvbG9yID0gbmV3IENvbG9yKCAweGZmZmZmZiApOyAvLyBkaWZmdXNlXG5cdHRoaXMuc3BlY3VsYXIgPSBuZXcgQ29sb3IoIDB4MTExMTExICk7XG5cdHRoaXMuc2hpbmluZXNzID0gMzA7XG5cblx0dGhpcy5tYXAgPSBudWxsO1xuXG5cdHRoaXMubGlnaHRNYXAgPSBudWxsO1xuXHR0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuYW9NYXAgPSBudWxsO1xuXHR0aGlzLmFvTWFwSW50ZW5zaXR5ID0gMS4wO1xuXG5cdHRoaXMuZW1pc3NpdmUgPSBuZXcgQ29sb3IoIDB4MDAwMDAwICk7XG5cdHRoaXMuZW1pc3NpdmVJbnRlbnNpdHkgPSAxLjA7XG5cdHRoaXMuZW1pc3NpdmVNYXAgPSBudWxsO1xuXG5cdHRoaXMuYnVtcE1hcCA9IG51bGw7XG5cdHRoaXMuYnVtcFNjYWxlID0gMTtcblxuXHR0aGlzLm5vcm1hbE1hcCA9IG51bGw7XG5cdHRoaXMubm9ybWFsU2NhbGUgPSBuZXcgVmVjdG9yMiggMSwgMSApO1xuXG5cdHRoaXMuZGlzcGxhY2VtZW50TWFwID0gbnVsbDtcblx0dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSA9IDE7XG5cdHRoaXMuZGlzcGxhY2VtZW50QmlhcyA9IDA7XG5cblx0dGhpcy5zcGVjdWxhck1hcCA9IG51bGw7XG5cblx0dGhpcy5hbHBoYU1hcCA9IG51bGw7XG5cblx0dGhpcy5lbnZNYXAgPSBudWxsO1xuXHR0aGlzLmNvbWJpbmUgPSBNdWx0aXBseU9wZXJhdGlvbjtcblx0dGhpcy5yZWZsZWN0aXZpdHkgPSAxO1xuXHR0aGlzLnJlZnJhY3Rpb25SYXRpbyA9IDAuOTg7XG5cblx0dGhpcy53aXJlZnJhbWUgPSBmYWxzZTtcblx0dGhpcy53aXJlZnJhbWVMaW5ld2lkdGggPSAxO1xuXHR0aGlzLndpcmVmcmFtZUxpbmVjYXAgPSAncm91bmQnO1xuXHR0aGlzLndpcmVmcmFtZUxpbmVqb2luID0gJ3JvdW5kJztcblxuXHR0aGlzLnNraW5uaW5nID0gZmFsc2U7XG5cdHRoaXMubW9ycGhUYXJnZXRzID0gZmFsc2U7XG5cdHRoaXMubW9ycGhOb3JtYWxzID0gZmFsc2U7XG5cblx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5NZXNoUGhvbmdNYXRlcmlhbC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBNYXRlcmlhbC5wcm90b3R5cGUgKTtcbk1lc2hQaG9uZ01hdGVyaWFsLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IE1lc2hQaG9uZ01hdGVyaWFsO1xuXG5NZXNoUGhvbmdNYXRlcmlhbC5wcm90b3R5cGUuaXNNZXNoUGhvbmdNYXRlcmlhbCA9IHRydWU7XG5cbk1lc2hQaG9uZ01hdGVyaWFsLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0TWF0ZXJpYWwucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblx0dGhpcy5zcGVjdWxhci5jb3B5KCBzb3VyY2Uuc3BlY3VsYXIgKTtcblx0dGhpcy5zaGluaW5lc3MgPSBzb3VyY2Uuc2hpbmluZXNzO1xuXG5cdHRoaXMubWFwID0gc291cmNlLm1hcDtcblxuXHR0aGlzLmxpZ2h0TWFwID0gc291cmNlLmxpZ2h0TWFwO1xuXHR0aGlzLmxpZ2h0TWFwSW50ZW5zaXR5ID0gc291cmNlLmxpZ2h0TWFwSW50ZW5zaXR5O1xuXG5cdHRoaXMuYW9NYXAgPSBzb3VyY2UuYW9NYXA7XG5cdHRoaXMuYW9NYXBJbnRlbnNpdHkgPSBzb3VyY2UuYW9NYXBJbnRlbnNpdHk7XG5cblx0dGhpcy5lbWlzc2l2ZS5jb3B5KCBzb3VyY2UuZW1pc3NpdmUgKTtcblx0dGhpcy5lbWlzc2l2ZU1hcCA9IHNvdXJjZS5lbWlzc2l2ZU1hcDtcblx0dGhpcy5lbWlzc2l2ZUludGVuc2l0eSA9IHNvdXJjZS5lbWlzc2l2ZUludGVuc2l0eTtcblxuXHR0aGlzLmJ1bXBNYXAgPSBzb3VyY2UuYnVtcE1hcDtcblx0dGhpcy5idW1wU2NhbGUgPSBzb3VyY2UuYnVtcFNjYWxlO1xuXG5cdHRoaXMubm9ybWFsTWFwID0gc291cmNlLm5vcm1hbE1hcDtcblx0dGhpcy5ub3JtYWxTY2FsZS5jb3B5KCBzb3VyY2Uubm9ybWFsU2NhbGUgKTtcblxuXHR0aGlzLmRpc3BsYWNlbWVudE1hcCA9IHNvdXJjZS5kaXNwbGFjZW1lbnRNYXA7XG5cdHRoaXMuZGlzcGxhY2VtZW50U2NhbGUgPSBzb3VyY2UuZGlzcGxhY2VtZW50U2NhbGU7XG5cdHRoaXMuZGlzcGxhY2VtZW50QmlhcyA9IHNvdXJjZS5kaXNwbGFjZW1lbnRCaWFzO1xuXG5cdHRoaXMuc3BlY3VsYXJNYXAgPSBzb3VyY2Uuc3BlY3VsYXJNYXA7XG5cblx0dGhpcy5hbHBoYU1hcCA9IHNvdXJjZS5hbHBoYU1hcDtcblxuXHR0aGlzLmVudk1hcCA9IHNvdXJjZS5lbnZNYXA7XG5cdHRoaXMuY29tYmluZSA9IHNvdXJjZS5jb21iaW5lO1xuXHR0aGlzLnJlZmxlY3Rpdml0eSA9IHNvdXJjZS5yZWZsZWN0aXZpdHk7XG5cdHRoaXMucmVmcmFjdGlvblJhdGlvID0gc291cmNlLnJlZnJhY3Rpb25SYXRpbztcblxuXHR0aGlzLndpcmVmcmFtZSA9IHNvdXJjZS53aXJlZnJhbWU7XG5cdHRoaXMud2lyZWZyYW1lTGluZXdpZHRoID0gc291cmNlLndpcmVmcmFtZUxpbmV3aWR0aDtcblx0dGhpcy53aXJlZnJhbWVMaW5lY2FwID0gc291cmNlLndpcmVmcmFtZUxpbmVjYXA7XG5cdHRoaXMud2lyZWZyYW1lTGluZWpvaW4gPSBzb3VyY2Uud2lyZWZyYW1lTGluZWpvaW47XG5cblx0dGhpcy5za2lubmluZyA9IHNvdXJjZS5za2lubmluZztcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXHR0aGlzLm1vcnBoTm9ybWFscyA9IHNvdXJjZS5tb3JwaE5vcm1hbHM7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciB0YWthaGlyb3ggLyBodHRwOi8vZ2l0aHViLmNvbS90YWthaGlyb3hcbiAqXG4gKiBwYXJhbWV0ZXJzID0ge1xuICogIGdyYWRpZW50TWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApXG4gKiB9XG4gKi9cblxuZnVuY3Rpb24gTWVzaFRvb25NYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNZXNoUGhvbmdNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5kZWZpbmVzID0geyAnVE9PTic6ICcnIH07XG5cblx0dGhpcy50eXBlID0gJ01lc2hUb29uTWF0ZXJpYWwnO1xuXG5cdHRoaXMuZ3JhZGllbnRNYXAgPSBudWxsO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuTWVzaFRvb25NYXRlcmlhbC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBNZXNoUGhvbmdNYXRlcmlhbC5wcm90b3R5cGUgKTtcbk1lc2hUb29uTWF0ZXJpYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTWVzaFRvb25NYXRlcmlhbDtcblxuTWVzaFRvb25NYXRlcmlhbC5wcm90b3R5cGUuaXNNZXNoVG9vbk1hdGVyaWFsID0gdHJ1ZTtcblxuTWVzaFRvb25NYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1lc2hQaG9uZ01hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuZ3JhZGllbnRNYXAgPSBzb3VyY2UuZ3JhZGllbnRNYXA7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICpcbiAqIHBhcmFtZXRlcnMgPSB7XG4gKiAgb3BhY2l0eTogPGZsb2F0PixcbiAqXG4gKiAgYnVtcE1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBidW1wU2NhbGU6IDxmbG9hdD4sXG4gKlxuICogIG5vcm1hbE1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBub3JtYWxTY2FsZTogPFZlY3RvcjI+LFxuICpcbiAqICBkaXNwbGFjZW1lbnRNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKiAgZGlzcGxhY2VtZW50U2NhbGU6IDxmbG9hdD4sXG4gKiAgZGlzcGxhY2VtZW50QmlhczogPGZsb2F0PixcbiAqXG4gKiAgd2lyZWZyYW1lOiA8Ym9vbGVhbj4sXG4gKiAgd2lyZWZyYW1lTGluZXdpZHRoOiA8ZmxvYXQ+XG4gKlxuICogIHNraW5uaW5nOiA8Ym9vbD4sXG4gKiAgbW9ycGhUYXJnZXRzOiA8Ym9vbD4sXG4gKiAgbW9ycGhOb3JtYWxzOiA8Ym9vbD5cbiAqIH1cbiAqL1xuXG5mdW5jdGlvbiBNZXNoTm9ybWFsTWF0ZXJpYWwoIHBhcmFtZXRlcnMgKSB7XG5cblx0TWF0ZXJpYWwuY2FsbCggdGhpcywgcGFyYW1ldGVycyApO1xuXG5cdHRoaXMudHlwZSA9ICdNZXNoTm9ybWFsTWF0ZXJpYWwnO1xuXG5cdHRoaXMuYnVtcE1hcCA9IG51bGw7XG5cdHRoaXMuYnVtcFNjYWxlID0gMTtcblxuXHR0aGlzLm5vcm1hbE1hcCA9IG51bGw7XG5cdHRoaXMubm9ybWFsU2NhbGUgPSBuZXcgVmVjdG9yMiggMSwgMSApO1xuXG5cdHRoaXMuZGlzcGxhY2VtZW50TWFwID0gbnVsbDtcblx0dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSA9IDE7XG5cdHRoaXMuZGlzcGxhY2VtZW50QmlhcyA9IDA7XG5cblx0dGhpcy53aXJlZnJhbWUgPSBmYWxzZTtcblx0dGhpcy53aXJlZnJhbWVMaW5ld2lkdGggPSAxO1xuXG5cdHRoaXMuZm9nID0gZmFsc2U7XG5cdHRoaXMubGlnaHRzID0gZmFsc2U7XG5cblx0dGhpcy5za2lubmluZyA9IGZhbHNlO1xuXHR0aGlzLm1vcnBoVGFyZ2V0cyA9IGZhbHNlO1xuXHR0aGlzLm1vcnBoTm9ybWFscyA9IGZhbHNlO1xuXG5cdHRoaXMuc2V0VmFsdWVzKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuTWVzaE5vcm1hbE1hdGVyaWFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE1hdGVyaWFsLnByb3RvdHlwZSApO1xuTWVzaE5vcm1hbE1hdGVyaWFsLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IE1lc2hOb3JtYWxNYXRlcmlhbDtcblxuTWVzaE5vcm1hbE1hdGVyaWFsLnByb3RvdHlwZS5pc01lc2hOb3JtYWxNYXRlcmlhbCA9IHRydWU7XG5cbk1lc2hOb3JtYWxNYXRlcmlhbC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdHRoaXMuYnVtcE1hcCA9IHNvdXJjZS5idW1wTWFwO1xuXHR0aGlzLmJ1bXBTY2FsZSA9IHNvdXJjZS5idW1wU2NhbGU7XG5cblx0dGhpcy5ub3JtYWxNYXAgPSBzb3VyY2Uubm9ybWFsTWFwO1xuXHR0aGlzLm5vcm1hbFNjYWxlLmNvcHkoIHNvdXJjZS5ub3JtYWxTY2FsZSApO1xuXG5cdHRoaXMuZGlzcGxhY2VtZW50TWFwID0gc291cmNlLmRpc3BsYWNlbWVudE1hcDtcblx0dGhpcy5kaXNwbGFjZW1lbnRTY2FsZSA9IHNvdXJjZS5kaXNwbGFjZW1lbnRTY2FsZTtcblx0dGhpcy5kaXNwbGFjZW1lbnRCaWFzID0gc291cmNlLmRpc3BsYWNlbWVudEJpYXM7XG5cblx0dGhpcy53aXJlZnJhbWUgPSBzb3VyY2Uud2lyZWZyYW1lO1xuXHR0aGlzLndpcmVmcmFtZUxpbmV3aWR0aCA9IHNvdXJjZS53aXJlZnJhbWVMaW5ld2lkdGg7XG5cblx0dGhpcy5za2lubmluZyA9IHNvdXJjZS5za2lubmluZztcblx0dGhpcy5tb3JwaFRhcmdldHMgPSBzb3VyY2UubW9ycGhUYXJnZXRzO1xuXHR0aGlzLm1vcnBoTm9ybWFscyA9IHNvdXJjZS5tb3JwaE5vcm1hbHM7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKlxuICogcGFyYW1ldGVycyA9IHtcbiAqICBjb2xvcjogPGhleD4sXG4gKiAgb3BhY2l0eTogPGZsb2F0PixcbiAqXG4gKiAgbWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBsaWdodE1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBsaWdodE1hcEludGVuc2l0eTogPGZsb2F0PlxuICpcbiAqICBhb01hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqICBhb01hcEludGVuc2l0eTogPGZsb2F0PlxuICpcbiAqICBlbWlzc2l2ZTogPGhleD4sXG4gKiAgZW1pc3NpdmVJbnRlbnNpdHk6IDxmbG9hdD5cbiAqICBlbWlzc2l2ZU1hcDogbmV3IFRIUkVFLlRleHR1cmUoIDxJbWFnZT4gKSxcbiAqXG4gKiAgc3BlY3VsYXJNYXA6IG5ldyBUSFJFRS5UZXh0dXJlKCA8SW1hZ2U+ICksXG4gKlxuICogIGFscGhhTWFwOiBuZXcgVEhSRUUuVGV4dHVyZSggPEltYWdlPiApLFxuICpcbiAqICBlbnZNYXA6IG5ldyBUSFJFRS5UZXh0dXJlQ3ViZSggW3Bvc3gsIG5lZ3gsIHBvc3ksIG5lZ3ksIHBvc3osIG5lZ3pdICksXG4gKiAgY29tYmluZTogVEhSRUUuTXVsdGlwbHksXG4gKiAgcmVmbGVjdGl2aXR5OiA8ZmxvYXQ+LFxuICogIHJlZnJhY3Rpb25SYXRpbzogPGZsb2F0PixcbiAqXG4gKiAgd2lyZWZyYW1lOiA8Ym9vbGVhbj4sXG4gKiAgd2lyZWZyYW1lTGluZXdpZHRoOiA8ZmxvYXQ+LFxuICpcbiAqICBza2lubmluZzogPGJvb2w+LFxuICogIG1vcnBoVGFyZ2V0czogPGJvb2w+LFxuICogIG1vcnBoTm9ybWFsczogPGJvb2w+XG4gKiB9XG4gKi9cblxuZnVuY3Rpb24gTWVzaExhbWJlcnRNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ01lc2hMYW1iZXJ0TWF0ZXJpYWwnO1xuXG5cdHRoaXMuY29sb3IgPSBuZXcgQ29sb3IoIDB4ZmZmZmZmICk7IC8vIGRpZmZ1c2VcblxuXHR0aGlzLm1hcCA9IG51bGw7XG5cblx0dGhpcy5saWdodE1hcCA9IG51bGw7XG5cdHRoaXMubGlnaHRNYXBJbnRlbnNpdHkgPSAxLjA7XG5cblx0dGhpcy5hb01hcCA9IG51bGw7XG5cdHRoaXMuYW9NYXBJbnRlbnNpdHkgPSAxLjA7XG5cblx0dGhpcy5lbWlzc2l2ZSA9IG5ldyBDb2xvciggMHgwMDAwMDAgKTtcblx0dGhpcy5lbWlzc2l2ZUludGVuc2l0eSA9IDEuMDtcblx0dGhpcy5lbWlzc2l2ZU1hcCA9IG51bGw7XG5cblx0dGhpcy5zcGVjdWxhck1hcCA9IG51bGw7XG5cblx0dGhpcy5hbHBoYU1hcCA9IG51bGw7XG5cblx0dGhpcy5lbnZNYXAgPSBudWxsO1xuXHR0aGlzLmNvbWJpbmUgPSBNdWx0aXBseU9wZXJhdGlvbjtcblx0dGhpcy5yZWZsZWN0aXZpdHkgPSAxO1xuXHR0aGlzLnJlZnJhY3Rpb25SYXRpbyA9IDAuOTg7XG5cblx0dGhpcy53aXJlZnJhbWUgPSBmYWxzZTtcblx0dGhpcy53aXJlZnJhbWVMaW5ld2lkdGggPSAxO1xuXHR0aGlzLndpcmVmcmFtZUxpbmVjYXAgPSAncm91bmQnO1xuXHR0aGlzLndpcmVmcmFtZUxpbmVqb2luID0gJ3JvdW5kJztcblxuXHR0aGlzLnNraW5uaW5nID0gZmFsc2U7XG5cdHRoaXMubW9ycGhUYXJnZXRzID0gZmFsc2U7XG5cdHRoaXMubW9ycGhOb3JtYWxzID0gZmFsc2U7XG5cblx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5NZXNoTGFtYmVydE1hdGVyaWFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE1hdGVyaWFsLnByb3RvdHlwZSApO1xuTWVzaExhbWJlcnRNYXRlcmlhbC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBNZXNoTGFtYmVydE1hdGVyaWFsO1xuXG5NZXNoTGFtYmVydE1hdGVyaWFsLnByb3RvdHlwZS5pc01lc2hMYW1iZXJ0TWF0ZXJpYWwgPSB0cnVlO1xuXG5NZXNoTGFtYmVydE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0TWF0ZXJpYWwucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblxuXHR0aGlzLm1hcCA9IHNvdXJjZS5tYXA7XG5cblx0dGhpcy5saWdodE1hcCA9IHNvdXJjZS5saWdodE1hcDtcblx0dGhpcy5saWdodE1hcEludGVuc2l0eSA9IHNvdXJjZS5saWdodE1hcEludGVuc2l0eTtcblxuXHR0aGlzLmFvTWFwID0gc291cmNlLmFvTWFwO1xuXHR0aGlzLmFvTWFwSW50ZW5zaXR5ID0gc291cmNlLmFvTWFwSW50ZW5zaXR5O1xuXG5cdHRoaXMuZW1pc3NpdmUuY29weSggc291cmNlLmVtaXNzaXZlICk7XG5cdHRoaXMuZW1pc3NpdmVNYXAgPSBzb3VyY2UuZW1pc3NpdmVNYXA7XG5cdHRoaXMuZW1pc3NpdmVJbnRlbnNpdHkgPSBzb3VyY2UuZW1pc3NpdmVJbnRlbnNpdHk7XG5cblx0dGhpcy5zcGVjdWxhck1hcCA9IHNvdXJjZS5zcGVjdWxhck1hcDtcblxuXHR0aGlzLmFscGhhTWFwID0gc291cmNlLmFscGhhTWFwO1xuXG5cdHRoaXMuZW52TWFwID0gc291cmNlLmVudk1hcDtcblx0dGhpcy5jb21iaW5lID0gc291cmNlLmNvbWJpbmU7XG5cdHRoaXMucmVmbGVjdGl2aXR5ID0gc291cmNlLnJlZmxlY3Rpdml0eTtcblx0dGhpcy5yZWZyYWN0aW9uUmF0aW8gPSBzb3VyY2UucmVmcmFjdGlvblJhdGlvO1xuXG5cdHRoaXMud2lyZWZyYW1lID0gc291cmNlLndpcmVmcmFtZTtcblx0dGhpcy53aXJlZnJhbWVMaW5ld2lkdGggPSBzb3VyY2Uud2lyZWZyYW1lTGluZXdpZHRoO1xuXHR0aGlzLndpcmVmcmFtZUxpbmVjYXAgPSBzb3VyY2Uud2lyZWZyYW1lTGluZWNhcDtcblx0dGhpcy53aXJlZnJhbWVMaW5lam9pbiA9IHNvdXJjZS53aXJlZnJhbWVMaW5lam9pbjtcblxuXHR0aGlzLnNraW5uaW5nID0gc291cmNlLnNraW5uaW5nO1xuXHR0aGlzLm1vcnBoVGFyZ2V0cyA9IHNvdXJjZS5tb3JwaFRhcmdldHM7XG5cdHRoaXMubW9ycGhOb3JtYWxzID0gc291cmNlLm1vcnBoTm9ybWFscztcblxuXHRyZXR1cm4gdGhpcztcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICpcbiAqIHBhcmFtZXRlcnMgPSB7XG4gKiAgY29sb3I6IDxoZXg+LFxuICogIG9wYWNpdHk6IDxmbG9hdD4sXG4gKlxuICogIGxpbmV3aWR0aDogPGZsb2F0PixcbiAqXG4gKiAgc2NhbGU6IDxmbG9hdD4sXG4gKiAgZGFzaFNpemU6IDxmbG9hdD4sXG4gKiAgZ2FwU2l6ZTogPGZsb2F0PlxuICogfVxuICovXG5cbmZ1bmN0aW9uIExpbmVEYXNoZWRNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRNYXRlcmlhbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0xpbmVEYXNoZWRNYXRlcmlhbCc7XG5cblx0dGhpcy5jb2xvciA9IG5ldyBDb2xvciggMHhmZmZmZmYgKTtcblxuXHR0aGlzLmxpbmV3aWR0aCA9IDE7XG5cblx0dGhpcy5zY2FsZSA9IDE7XG5cdHRoaXMuZGFzaFNpemUgPSAzO1xuXHR0aGlzLmdhcFNpemUgPSAxO1xuXG5cdHRoaXMubGlnaHRzID0gZmFsc2U7XG5cblx0dGhpcy5zZXRWYWx1ZXMoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5MaW5lRGFzaGVkTWF0ZXJpYWwucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWF0ZXJpYWwucHJvdG90eXBlICk7XG5MaW5lRGFzaGVkTWF0ZXJpYWwucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGluZURhc2hlZE1hdGVyaWFsO1xuXG5MaW5lRGFzaGVkTWF0ZXJpYWwucHJvdG90eXBlLmlzTGluZURhc2hlZE1hdGVyaWFsID0gdHJ1ZTtcblxuTGluZURhc2hlZE1hdGVyaWFsLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0TWF0ZXJpYWwucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblxuXHR0aGlzLmxpbmV3aWR0aCA9IHNvdXJjZS5saW5ld2lkdGg7XG5cblx0dGhpcy5zY2FsZSA9IHNvdXJjZS5zY2FsZTtcblx0dGhpcy5kYXNoU2l6ZSA9IHNvdXJjZS5kYXNoU2l6ZTtcblx0dGhpcy5nYXBTaXplID0gc291cmNlLmdhcFNpemU7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cblxuXG52YXIgTWF0ZXJpYWxzID0gT2JqZWN0LmZyZWV6ZSh7XG5cdFNoYWRvd01hdGVyaWFsOiBTaGFkb3dNYXRlcmlhbCxcblx0U3ByaXRlTWF0ZXJpYWw6IFNwcml0ZU1hdGVyaWFsLFxuXHRSYXdTaGFkZXJNYXRlcmlhbDogUmF3U2hhZGVyTWF0ZXJpYWwsXG5cdFNoYWRlck1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbCxcblx0UG9pbnRzTWF0ZXJpYWw6IFBvaW50c01hdGVyaWFsLFxuXHRNZXNoUGh5c2ljYWxNYXRlcmlhbDogTWVzaFBoeXNpY2FsTWF0ZXJpYWwsXG5cdE1lc2hTdGFuZGFyZE1hdGVyaWFsOiBNZXNoU3RhbmRhcmRNYXRlcmlhbCxcblx0TWVzaFBob25nTWF0ZXJpYWw6IE1lc2hQaG9uZ01hdGVyaWFsLFxuXHRNZXNoVG9vbk1hdGVyaWFsOiBNZXNoVG9vbk1hdGVyaWFsLFxuXHRNZXNoTm9ybWFsTWF0ZXJpYWw6IE1lc2hOb3JtYWxNYXRlcmlhbCxcblx0TWVzaExhbWJlcnRNYXRlcmlhbDogTWVzaExhbWJlcnRNYXRlcmlhbCxcblx0TWVzaERlcHRoTWF0ZXJpYWw6IE1lc2hEZXB0aE1hdGVyaWFsLFxuXHRNZXNoQmFzaWNNYXRlcmlhbDogTWVzaEJhc2ljTWF0ZXJpYWwsXG5cdExpbmVEYXNoZWRNYXRlcmlhbDogTGluZURhc2hlZE1hdGVyaWFsLFxuXHRMaW5lQmFzaWNNYXRlcmlhbDogTGluZUJhc2ljTWF0ZXJpYWwsXG5cdE1hdGVyaWFsOiBNYXRlcmlhbFxufSk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG52YXIgQ2FjaGUgPSB7XG5cblx0ZW5hYmxlZDogZmFsc2UsXG5cblx0ZmlsZXM6IHt9LFxuXG5cdGFkZDogZnVuY3Rpb24gKCBrZXksIGZpbGUgKSB7XG5cblx0XHRpZiAoIHRoaXMuZW5hYmxlZCA9PT0gZmFsc2UgKSByZXR1cm47XG5cblx0XHQvLyBjb25zb2xlLmxvZyggJ1RIUkVFLkNhY2hlJywgJ0FkZGluZyBrZXk6Jywga2V5ICk7XG5cblx0XHR0aGlzLmZpbGVzWyBrZXkgXSA9IGZpbGU7XG5cblx0fSxcblxuXHRnZXQ6IGZ1bmN0aW9uICgga2V5ICkge1xuXG5cdFx0aWYgKCB0aGlzLmVuYWJsZWQgPT09IGZhbHNlICkgcmV0dXJuO1xuXG5cdFx0Ly8gY29uc29sZS5sb2coICdUSFJFRS5DYWNoZScsICdDaGVja2luZyBrZXk6Jywga2V5ICk7XG5cblx0XHRyZXR1cm4gdGhpcy5maWxlc1sga2V5IF07XG5cblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uICgga2V5ICkge1xuXG5cdFx0ZGVsZXRlIHRoaXMuZmlsZXNbIGtleSBdO1xuXG5cdH0sXG5cblx0Y2xlYXI6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZmlsZXMgPSB7fTtcblxuXHR9XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBMb2FkaW5nTWFuYWdlciggb25Mb2FkLCBvblByb2dyZXNzLCBvbkVycm9yICkge1xuXG5cdHZhciBzY29wZSA9IHRoaXM7XG5cblx0dmFyIGlzTG9hZGluZyA9IGZhbHNlLCBpdGVtc0xvYWRlZCA9IDAsIGl0ZW1zVG90YWwgPSAwO1xuXG5cdHRoaXMub25TdGFydCA9IHVuZGVmaW5lZDtcblx0dGhpcy5vbkxvYWQgPSBvbkxvYWQ7XG5cdHRoaXMub25Qcm9ncmVzcyA9IG9uUHJvZ3Jlc3M7XG5cdHRoaXMub25FcnJvciA9IG9uRXJyb3I7XG5cblx0dGhpcy5pdGVtU3RhcnQgPSBmdW5jdGlvbiAoIHVybCApIHtcblxuXHRcdGl0ZW1zVG90YWwgKys7XG5cblx0XHRpZiAoIGlzTG9hZGluZyA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGlmICggc2NvcGUub25TdGFydCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHNjb3BlLm9uU3RhcnQoIHVybCwgaXRlbXNMb2FkZWQsIGl0ZW1zVG90YWwgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aXNMb2FkaW5nID0gdHJ1ZTtcblxuXHR9O1xuXG5cdHRoaXMuaXRlbUVuZCA9IGZ1bmN0aW9uICggdXJsICkge1xuXG5cdFx0aXRlbXNMb2FkZWQgKys7XG5cblx0XHRpZiAoIHNjb3BlLm9uUHJvZ3Jlc3MgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0c2NvcGUub25Qcm9ncmVzcyggdXJsLCBpdGVtc0xvYWRlZCwgaXRlbXNUb3RhbCApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBpdGVtc0xvYWRlZCA9PT0gaXRlbXNUb3RhbCApIHtcblxuXHRcdFx0aXNMb2FkaW5nID0gZmFsc2U7XG5cblx0XHRcdGlmICggc2NvcGUub25Mb2FkICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0c2NvcGUub25Mb2FkKCk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9O1xuXG5cdHRoaXMuaXRlbUVycm9yID0gZnVuY3Rpb24gKCB1cmwgKSB7XG5cblx0XHRpZiAoIHNjb3BlLm9uRXJyb3IgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0c2NvcGUub25FcnJvciggdXJsICk7XG5cblx0XHR9XG5cblx0fTtcblxufVxuXG52YXIgRGVmYXVsdExvYWRpbmdNYW5hZ2VyID0gbmV3IExvYWRpbmdNYW5hZ2VyKCk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBGaWxlTG9hZGVyKCBtYW5hZ2VyICkge1xuXG5cdHRoaXMubWFuYWdlciA9ICggbWFuYWdlciAhPT0gdW5kZWZpbmVkICkgPyBtYW5hZ2VyIDogRGVmYXVsdExvYWRpbmdNYW5hZ2VyO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEZpbGVMb2FkZXIucHJvdG90eXBlLCB7XG5cblx0bG9hZDogZnVuY3Rpb24gKCB1cmwsIG9uTG9hZCwgb25Qcm9ncmVzcywgb25FcnJvciApIHtcblxuXHRcdGlmICggdXJsID09PSB1bmRlZmluZWQgKSB1cmwgPSAnJztcblxuXHRcdGlmICggdGhpcy5wYXRoICE9PSB1bmRlZmluZWQgKSB1cmwgPSB0aGlzLnBhdGggKyB1cmw7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGNhY2hlZCA9IENhY2hlLmdldCggdXJsICk7XG5cblx0XHRpZiAoIGNhY2hlZCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1TdGFydCggdXJsICk7XG5cblx0XHRcdHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0XHRpZiAoIG9uTG9hZCApIG9uTG9hZCggY2FjaGVkICk7XG5cblx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRW5kKCB1cmwgKTtcblxuXHRcdFx0fSwgMCApO1xuXG5cdFx0XHRyZXR1cm4gY2FjaGVkO1xuXG5cdFx0fVxuXG5cdFx0Ly8gQ2hlY2sgZm9yIGRhdGE6IFVSSVxuXHRcdHZhciBkYXRhVXJpUmVnZXggPSAvXmRhdGE6KC4qPykoO2Jhc2U2NCk/LCguKikkLztcblx0XHR2YXIgZGF0YVVyaVJlZ2V4UmVzdWx0ID0gdXJsLm1hdGNoKCBkYXRhVXJpUmVnZXggKTtcblxuXHRcdC8vIFNhZmFyaSBjYW4gbm90IGhhbmRsZSBEYXRhIFVSSXMgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdCBzbyBwcm9jZXNzIG1hbnVhbGx5XG5cdFx0aWYgKCBkYXRhVXJpUmVnZXhSZXN1bHQgKSB7XG5cblx0XHRcdHZhciBtaW1lVHlwZSA9IGRhdGFVcmlSZWdleFJlc3VsdFsgMSBdO1xuXHRcdFx0dmFyIGlzQmFzZTY0ID0gISEgZGF0YVVyaVJlZ2V4UmVzdWx0WyAyIF07XG5cdFx0XHR2YXIgZGF0YSA9IGRhdGFVcmlSZWdleFJlc3VsdFsgMyBdO1xuXG5cdFx0XHRkYXRhID0gd2luZG93LmRlY29kZVVSSUNvbXBvbmVudCggZGF0YSApO1xuXG5cdFx0XHRpZiAoIGlzQmFzZTY0ICkgZGF0YSA9IHdpbmRvdy5hdG9iKCBkYXRhICk7XG5cblx0XHRcdHRyeSB7XG5cblx0XHRcdFx0dmFyIHJlc3BvbnNlO1xuXHRcdFx0XHR2YXIgcmVzcG9uc2VUeXBlID0gKCB0aGlzLnJlc3BvbnNlVHlwZSB8fCAnJyApLnRvTG93ZXJDYXNlKCk7XG5cblx0XHRcdFx0c3dpdGNoICggcmVzcG9uc2VUeXBlICkge1xuXG5cdFx0XHRcdFx0Y2FzZSAnYXJyYXlidWZmZXInOlxuXHRcdFx0XHRcdGNhc2UgJ2Jsb2InOlxuXG5cdFx0XHRcdFx0IFx0cmVzcG9uc2UgPSBuZXcgQXJyYXlCdWZmZXIoIGRhdGEubGVuZ3RoICk7XG5cblx0XHRcdFx0XHRcdHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoIHJlc3BvbnNlICk7XG5cblx0XHRcdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdHZpZXdbIGkgXSA9IGRhdGEuY2hhckNvZGVBdCggaSApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICggcmVzcG9uc2VUeXBlID09PSAnYmxvYicgKSB7XG5cblx0XHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBuZXcgQmxvYiggWyByZXNwb25zZSBdLCB7IHR5cGU6IG1pbWVUeXBlIH0gKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgJ2RvY3VtZW50JzpcblxuXHRcdFx0XHRcdFx0dmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyggZGF0YSwgbWltZVR5cGUgKTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdqc29uJzpcblxuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBKU09OLnBhcnNlKCBkYXRhICk7XG5cblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0ZGVmYXVsdDogLy8gJ3RleHQnIG9yIG90aGVyXG5cblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gZGF0YTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFdhaXQgZm9yIG5leHQgYnJvd3NlciB0aWNrXG5cdFx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0XHRpZiAoIG9uTG9hZCApIG9uTG9hZCggcmVzcG9uc2UgKTtcblxuXHRcdFx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVuZCggdXJsICk7XG5cblx0XHRcdFx0fSwgMCApO1xuXG5cdFx0XHR9IGNhdGNoICggZXJyb3IgKSB7XG5cblx0XHRcdFx0Ly8gV2FpdCBmb3IgbmV4dCBicm93c2VyIHRpY2tcblx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0XHRcdGlmICggb25FcnJvciApIG9uRXJyb3IoIGVycm9yICk7XG5cblx0XHRcdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1FbmQoIHVybCApO1xuXHRcdFx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVycm9yKCB1cmwgKTtcblxuXHRcdFx0XHR9LCAwICk7XG5cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdFx0XHRyZXF1ZXN0Lm9wZW4oICdHRVQnLCB1cmwsIHRydWUgKTtcblxuXHRcdFx0cmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCAnbG9hZCcsIGZ1bmN0aW9uICggZXZlbnQgKSB7XG5cblx0XHRcdFx0dmFyIHJlc3BvbnNlID0gZXZlbnQudGFyZ2V0LnJlc3BvbnNlO1xuXG5cdFx0XHRcdENhY2hlLmFkZCggdXJsLCByZXNwb25zZSApO1xuXG5cdFx0XHRcdGlmICggdGhpcy5zdGF0dXMgPT09IDIwMCApIHtcblxuXHRcdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCByZXNwb25zZSApO1xuXG5cdFx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRW5kKCB1cmwgKTtcblxuXHRcdFx0XHR9IGVsc2UgaWYgKCB0aGlzLnN0YXR1cyA9PT0gMCApIHtcblxuXHRcdFx0XHRcdC8vIFNvbWUgYnJvd3NlcnMgcmV0dXJuIEhUVFAgU3RhdHVzIDAgd2hlbiB1c2luZyBub24taHR0cCBwcm90b2NvbFxuXHRcdFx0XHRcdC8vIGUuZy4gJ2ZpbGU6Ly8nIG9yICdkYXRhOi8vJy4gSGFuZGxlIGFzIHN1Y2Nlc3MuXG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5GaWxlTG9hZGVyOiBIVFRQIFN0YXR1cyAwIHJlY2VpdmVkLicgKTtcblxuXHRcdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCByZXNwb25zZSApO1xuXG5cdFx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRW5kKCB1cmwgKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0aWYgKCBvbkVycm9yICkgb25FcnJvciggZXZlbnQgKTtcblxuXHRcdFx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVuZCggdXJsICk7XG5cdFx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRXJyb3IoIHVybCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSwgZmFsc2UgKTtcblxuXHRcdFx0aWYgKCBvblByb2dyZXNzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0cmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCAncHJvZ3Jlc3MnLCBmdW5jdGlvbiAoIGV2ZW50ICkge1xuXG5cdFx0XHRcdFx0b25Qcm9ncmVzcyggZXZlbnQgKTtcblxuXHRcdFx0XHR9LCBmYWxzZSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lciggJ2Vycm9yJywgZnVuY3Rpb24gKCBldmVudCApIHtcblxuXHRcdFx0XHRpZiAoIG9uRXJyb3IgKSBvbkVycm9yKCBldmVudCApO1xuXG5cdFx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVuZCggdXJsICk7XG5cdFx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVycm9yKCB1cmwgKTtcblxuXHRcdFx0fSwgZmFsc2UgKTtcblxuXHRcdFx0aWYgKCB0aGlzLnJlc3BvbnNlVHlwZSAhPT0gdW5kZWZpbmVkICkgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSB0aGlzLnJlc3BvbnNlVHlwZTtcblx0XHRcdGlmICggdGhpcy53aXRoQ3JlZGVudGlhbHMgIT09IHVuZGVmaW5lZCApIHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gdGhpcy53aXRoQ3JlZGVudGlhbHM7XG5cblx0XHRcdGlmICggcmVxdWVzdC5vdmVycmlkZU1pbWVUeXBlICkgcmVxdWVzdC5vdmVycmlkZU1pbWVUeXBlKCB0aGlzLm1pbWVUeXBlICE9PSB1bmRlZmluZWQgPyB0aGlzLm1pbWVUeXBlIDogJ3RleHQvcGxhaW4nICk7XG5cblx0XHRcdGZvciAoIHZhciBoZWFkZXIgaW4gdGhpcy5yZXF1ZXN0SGVhZGVyICkge1xuXG5cdFx0XHRcdHJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlciggaGVhZGVyLCB0aGlzLnJlcXVlc3RIZWFkZXJbIGhlYWRlciBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0cmVxdWVzdC5zZW5kKCBudWxsICk7XG5cblx0XHR9XG5cblx0XHRzY29wZS5tYW5hZ2VyLml0ZW1TdGFydCggdXJsICk7XG5cblx0XHRyZXR1cm4gcmVxdWVzdDtcblxuXHR9LFxuXG5cdHNldFBhdGg6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLnBhdGggPSB2YWx1ZTtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFJlc3BvbnNlVHlwZTogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMucmVzcG9uc2VUeXBlID0gdmFsdWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRXaXRoQ3JlZGVudGlhbHM6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLndpdGhDcmVkZW50aWFscyA9IHZhbHVlO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0TWltZVR5cGU6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLm1pbWVUeXBlID0gdmFsdWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy5yZXF1ZXN0SGVhZGVyID0gdmFsdWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqXG4gKiBBYnN0cmFjdCBCYXNlIGNsYXNzIHRvIGJsb2NrIGJhc2VkIHRleHR1cmVzIGxvYWRlciAoZGRzLCBwdnIsIC4uLilcbiAqL1xuXG5mdW5jdGlvbiBDb21wcmVzc2VkVGV4dHVyZUxvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblxuXHQvLyBvdmVycmlkZSBpbiBzdWIgY2xhc3Nlc1xuXHR0aGlzLl9wYXJzZXIgPSBudWxsO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIENvbXByZXNzZWRUZXh0dXJlTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGltYWdlcyA9IFtdO1xuXG5cdFx0dmFyIHRleHR1cmUgPSBuZXcgQ29tcHJlc3NlZFRleHR1cmUoKTtcblx0XHR0ZXh0dXJlLmltYWdlID0gaW1hZ2VzO1xuXG5cdFx0dmFyIGxvYWRlciA9IG5ldyBGaWxlTG9hZGVyKCB0aGlzLm1hbmFnZXIgKTtcblx0XHRsb2FkZXIuc2V0UGF0aCggdGhpcy5wYXRoICk7XG5cdFx0bG9hZGVyLnNldFJlc3BvbnNlVHlwZSggJ2FycmF5YnVmZmVyJyApO1xuXG5cdFx0ZnVuY3Rpb24gbG9hZFRleHR1cmUoIGkgKSB7XG5cblx0XHRcdGxvYWRlci5sb2FkKCB1cmxbIGkgXSwgZnVuY3Rpb24gKCBidWZmZXIgKSB7XG5cblx0XHRcdFx0dmFyIHRleERhdGFzID0gc2NvcGUuX3BhcnNlciggYnVmZmVyLCB0cnVlICk7XG5cblx0XHRcdFx0aW1hZ2VzWyBpIF0gPSB7XG5cdFx0XHRcdFx0d2lkdGg6IHRleERhdGFzLndpZHRoLFxuXHRcdFx0XHRcdGhlaWdodDogdGV4RGF0YXMuaGVpZ2h0LFxuXHRcdFx0XHRcdGZvcm1hdDogdGV4RGF0YXMuZm9ybWF0LFxuXHRcdFx0XHRcdG1pcG1hcHM6IHRleERhdGFzLm1pcG1hcHNcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRsb2FkZWQgKz0gMTtcblxuXHRcdFx0XHRpZiAoIGxvYWRlZCA9PT0gNiApIHtcblxuXHRcdFx0XHRcdGlmICggdGV4RGF0YXMubWlwbWFwQ291bnQgPT09IDEgKVxuXHRcdFx0XHRcdFx0dGV4dHVyZS5taW5GaWx0ZXIgPSBMaW5lYXJGaWx0ZXI7XG5cblx0XHRcdFx0XHR0ZXh0dXJlLmZvcm1hdCA9IHRleERhdGFzLmZvcm1hdDtcblx0XHRcdFx0XHR0ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCB0ZXh0dXJlICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LCBvblByb2dyZXNzLCBvbkVycm9yICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHVybCApICkge1xuXG5cdFx0XHR2YXIgbG9hZGVkID0gMDtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBpbCA9IHVybC5sZW5ndGg7IGkgPCBpbDsgKysgaSApIHtcblxuXHRcdFx0XHRsb2FkVGV4dHVyZSggaSApO1xuXG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBjb21wcmVzc2VkIGN1YmVtYXAgdGV4dHVyZSBzdG9yZWQgaW4gYSBzaW5nbGUgRERTIGZpbGVcblxuXHRcdFx0bG9hZGVyLmxvYWQoIHVybCwgZnVuY3Rpb24gKCBidWZmZXIgKSB7XG5cblx0XHRcdFx0dmFyIHRleERhdGFzID0gc2NvcGUuX3BhcnNlciggYnVmZmVyLCB0cnVlICk7XG5cblx0XHRcdFx0aWYgKCB0ZXhEYXRhcy5pc0N1YmVtYXAgKSB7XG5cblx0XHRcdFx0XHR2YXIgZmFjZXMgPSB0ZXhEYXRhcy5taXBtYXBzLmxlbmd0aCAvIHRleERhdGFzLm1pcG1hcENvdW50O1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGYgPSAwOyBmIDwgZmFjZXM7IGYgKysgKSB7XG5cblx0XHRcdFx0XHRcdGltYWdlc1sgZiBdID0geyBtaXBtYXBzIDogW10gfTtcblxuXHRcdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGV4RGF0YXMubWlwbWFwQ291bnQ7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0aW1hZ2VzWyBmIF0ubWlwbWFwcy5wdXNoKCB0ZXhEYXRhcy5taXBtYXBzWyBmICogdGV4RGF0YXMubWlwbWFwQ291bnQgKyBpIF0gKTtcblx0XHRcdFx0XHRcdFx0aW1hZ2VzWyBmIF0uZm9ybWF0ID0gdGV4RGF0YXMuZm9ybWF0O1xuXHRcdFx0XHRcdFx0XHRpbWFnZXNbIGYgXS53aWR0aCA9IHRleERhdGFzLndpZHRoO1xuXHRcdFx0XHRcdFx0XHRpbWFnZXNbIGYgXS5oZWlnaHQgPSB0ZXhEYXRhcy5oZWlnaHQ7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0dGV4dHVyZS5pbWFnZS53aWR0aCA9IHRleERhdGFzLndpZHRoO1xuXHRcdFx0XHRcdHRleHR1cmUuaW1hZ2UuaGVpZ2h0ID0gdGV4RGF0YXMuaGVpZ2h0O1xuXHRcdFx0XHRcdHRleHR1cmUubWlwbWFwcyA9IHRleERhdGFzLm1pcG1hcHM7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggdGV4RGF0YXMubWlwbWFwQ291bnQgPT09IDEgKSB7XG5cblx0XHRcdFx0XHR0ZXh0dXJlLm1pbkZpbHRlciA9IExpbmVhckZpbHRlcjtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGV4dHVyZS5mb3JtYXQgPSB0ZXhEYXRhcy5mb3JtYXQ7XG5cdFx0XHRcdHRleHR1cmUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCB0ZXh0dXJlICk7XG5cblx0XHRcdH0sIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0ZXh0dXJlO1xuXG5cdH0sXG5cblx0c2V0UGF0aDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMucGF0aCA9IHZhbHVlO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgTmlrb3MgTS4gLyBodHRwczovL2dpdGh1Yi5jb20vZm9vMTIzL1xuICpcbiAqIEFic3RyYWN0IEJhc2UgY2xhc3MgdG8gbG9hZCBnZW5lcmljIGJpbmFyeSB0ZXh0dXJlcyBmb3JtYXRzIChyZ2JlLCBoZHIsIC4uLilcbiAqL1xuXG5mdW5jdGlvbiBEYXRhVGV4dHVyZUxvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblxuXHQvLyBvdmVycmlkZSBpbiBzdWIgY2xhc3Nlc1xuXHR0aGlzLl9wYXJzZXIgPSBudWxsO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIERhdGFUZXh0dXJlTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIHRleHR1cmUgPSBuZXcgRGF0YVRleHR1cmUoKTtcblxuXHRcdHZhciBsb2FkZXIgPSBuZXcgRmlsZUxvYWRlciggdGhpcy5tYW5hZ2VyICk7XG5cdFx0bG9hZGVyLnNldFJlc3BvbnNlVHlwZSggJ2FycmF5YnVmZmVyJyApO1xuXG5cdFx0bG9hZGVyLmxvYWQoIHVybCwgZnVuY3Rpb24gKCBidWZmZXIgKSB7XG5cblx0XHRcdHZhciB0ZXhEYXRhID0gc2NvcGUuX3BhcnNlciggYnVmZmVyICk7XG5cblx0XHRcdGlmICggISB0ZXhEYXRhICkgcmV0dXJuO1xuXG5cdFx0XHRpZiAoIHVuZGVmaW5lZCAhPT0gdGV4RGF0YS5pbWFnZSApIHtcblxuXHRcdFx0XHR0ZXh0dXJlLmltYWdlID0gdGV4RGF0YS5pbWFnZTtcblxuXHRcdFx0fSBlbHNlIGlmICggdW5kZWZpbmVkICE9PSB0ZXhEYXRhLmRhdGEgKSB7XG5cblx0XHRcdFx0dGV4dHVyZS5pbWFnZS53aWR0aCA9IHRleERhdGEud2lkdGg7XG5cdFx0XHRcdHRleHR1cmUuaW1hZ2UuaGVpZ2h0ID0gdGV4RGF0YS5oZWlnaHQ7XG5cdFx0XHRcdHRleHR1cmUuaW1hZ2UuZGF0YSA9IHRleERhdGEuZGF0YTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0ZXh0dXJlLndyYXBTID0gdW5kZWZpbmVkICE9PSB0ZXhEYXRhLndyYXBTID8gdGV4RGF0YS53cmFwUyA6IENsYW1wVG9FZGdlV3JhcHBpbmc7XG5cdFx0XHR0ZXh0dXJlLndyYXBUID0gdW5kZWZpbmVkICE9PSB0ZXhEYXRhLndyYXBUID8gdGV4RGF0YS53cmFwVCA6IENsYW1wVG9FZGdlV3JhcHBpbmc7XG5cblx0XHRcdHRleHR1cmUubWFnRmlsdGVyID0gdW5kZWZpbmVkICE9PSB0ZXhEYXRhLm1hZ0ZpbHRlciA/IHRleERhdGEubWFnRmlsdGVyIDogTGluZWFyRmlsdGVyO1xuXHRcdFx0dGV4dHVyZS5taW5GaWx0ZXIgPSB1bmRlZmluZWQgIT09IHRleERhdGEubWluRmlsdGVyID8gdGV4RGF0YS5taW5GaWx0ZXIgOiBMaW5lYXJNaXBNYXBMaW5lYXJGaWx0ZXI7XG5cblx0XHRcdHRleHR1cmUuYW5pc290cm9weSA9IHVuZGVmaW5lZCAhPT0gdGV4RGF0YS5hbmlzb3Ryb3B5ID8gdGV4RGF0YS5hbmlzb3Ryb3B5IDogMTtcblxuXHRcdFx0aWYgKCB1bmRlZmluZWQgIT09IHRleERhdGEuZm9ybWF0ICkge1xuXG5cdFx0XHRcdHRleHR1cmUuZm9ybWF0ID0gdGV4RGF0YS5mb3JtYXQ7XG5cblx0XHRcdH1cblx0XHRcdGlmICggdW5kZWZpbmVkICE9PSB0ZXhEYXRhLnR5cGUgKSB7XG5cblx0XHRcdFx0dGV4dHVyZS50eXBlID0gdGV4RGF0YS50eXBlO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggdW5kZWZpbmVkICE9PSB0ZXhEYXRhLm1pcG1hcHMgKSB7XG5cblx0XHRcdFx0dGV4dHVyZS5taXBtYXBzID0gdGV4RGF0YS5taXBtYXBzO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggMSA9PT0gdGV4RGF0YS5taXBtYXBDb3VudCApIHtcblxuXHRcdFx0XHR0ZXh0dXJlLm1pbkZpbHRlciA9IExpbmVhckZpbHRlcjtcblxuXHRcdFx0fVxuXG5cdFx0XHR0ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCBvbkxvYWQgKSBvbkxvYWQoIHRleHR1cmUsIHRleERhdGEgKTtcblxuXHRcdH0sIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKTtcblxuXG5cdFx0cmV0dXJuIHRleHR1cmU7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBJbWFnZUxvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblxufVxuXG5PYmplY3QuYXNzaWduKCBJbWFnZUxvYWRlci5wcm90b3R5cGUsIHtcblxuXHRsb2FkOiBmdW5jdGlvbiAoIHVybCwgb25Mb2FkLCBvblByb2dyZXNzLCBvbkVycm9yICkge1xuXG5cdFx0aWYgKCB1cmwgPT09IHVuZGVmaW5lZCApIHVybCA9ICcnO1xuXG5cdFx0aWYgKCB0aGlzLnBhdGggIT09IHVuZGVmaW5lZCApIHVybCA9IHRoaXMucGF0aCArIHVybDtcblxuXHRcdHZhciBzY29wZSA9IHRoaXM7XG5cblx0XHR2YXIgY2FjaGVkID0gQ2FjaGUuZ2V0KCB1cmwgKTtcblxuXHRcdGlmICggY2FjaGVkICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbVN0YXJ0KCB1cmwgKTtcblxuXHRcdFx0c2V0VGltZW91dCggZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCBjYWNoZWQgKTtcblxuXHRcdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1FbmQoIHVybCApO1xuXG5cdFx0XHR9LCAwICk7XG5cblx0XHRcdHJldHVybiBjYWNoZWQ7XG5cblx0XHR9XG5cblx0XHR2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJywgJ2ltZycgKTtcblxuXHRcdGltYWdlLmFkZEV2ZW50TGlzdGVuZXIoICdsb2FkJywgZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRDYWNoZS5hZGQoIHVybCwgdGhpcyApO1xuXG5cdFx0XHRpZiAoIG9uTG9hZCApIG9uTG9hZCggdGhpcyApO1xuXG5cdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1FbmQoIHVybCApO1xuXG5cdFx0fSwgZmFsc2UgKTtcblxuXHRcdC8qXG5cdFx0aW1hZ2UuYWRkRXZlbnRMaXN0ZW5lciggJ3Byb2dyZXNzJywgZnVuY3Rpb24gKCBldmVudCApIHtcblxuXHRcdFx0aWYgKCBvblByb2dyZXNzICkgb25Qcm9ncmVzcyggZXZlbnQgKTtcblxuXHRcdH0sIGZhbHNlICk7XG5cdFx0Ki9cblxuXHRcdGltYWdlLmFkZEV2ZW50TGlzdGVuZXIoICdlcnJvcicsIGZ1bmN0aW9uICggZXZlbnQgKSB7XG5cblx0XHRcdGlmICggb25FcnJvciApIG9uRXJyb3IoIGV2ZW50ICk7XG5cblx0XHRcdHNjb3BlLm1hbmFnZXIuaXRlbUVuZCggdXJsICk7XG5cdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1FcnJvciggdXJsICk7XG5cblx0XHR9LCBmYWxzZSApO1xuXG5cdFx0aWYgKCB1cmwuc3Vic3RyKCAwLCA1ICkgIT09ICdkYXRhOicgKSB7XG5cblx0XHRcdGlmICggdGhpcy5jcm9zc09yaWdpbiAhPT0gdW5kZWZpbmVkICkgaW1hZ2UuY3Jvc3NPcmlnaW4gPSB0aGlzLmNyb3NzT3JpZ2luO1xuXG5cdFx0fVxuXG5cdFx0c2NvcGUubWFuYWdlci5pdGVtU3RhcnQoIHVybCApO1xuXG5cdFx0aW1hZ2Uuc3JjID0gdXJsO1xuXG5cdFx0cmV0dXJuIGltYWdlO1xuXG5cdH0sXG5cblx0c2V0Q3Jvc3NPcmlnaW46IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLmNyb3NzT3JpZ2luID0gdmFsdWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRQYXRoOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy5wYXRoID0gdmFsdWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBDdWJlVGV4dHVyZUxvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblxufVxuXG5PYmplY3QuYXNzaWduKCBDdWJlVGV4dHVyZUxvYWRlci5wcm90b3R5cGUsIHtcblxuXHRsb2FkOiBmdW5jdGlvbiAoIHVybHMsIG9uTG9hZCwgb25Qcm9ncmVzcywgb25FcnJvciApIHtcblxuXHRcdHZhciB0ZXh0dXJlID0gbmV3IEN1YmVUZXh0dXJlKCk7XG5cblx0XHR2YXIgbG9hZGVyID0gbmV3IEltYWdlTG9hZGVyKCB0aGlzLm1hbmFnZXIgKTtcblx0XHRsb2FkZXIuc2V0Q3Jvc3NPcmlnaW4oIHRoaXMuY3Jvc3NPcmlnaW4gKTtcblx0XHRsb2FkZXIuc2V0UGF0aCggdGhpcy5wYXRoICk7XG5cblx0XHR2YXIgbG9hZGVkID0gMDtcblxuXHRcdGZ1bmN0aW9uIGxvYWRUZXh0dXJlKCBpICkge1xuXG5cdFx0XHRsb2FkZXIubG9hZCggdXJsc1sgaSBdLCBmdW5jdGlvbiAoIGltYWdlICkge1xuXG5cdFx0XHRcdHRleHR1cmUuaW1hZ2VzWyBpIF0gPSBpbWFnZTtcblxuXHRcdFx0XHRsb2FkZWQgKys7XG5cblx0XHRcdFx0aWYgKCBsb2FkZWQgPT09IDYgKSB7XG5cblx0XHRcdFx0XHR0ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0XHRcdGlmICggb25Mb2FkICkgb25Mb2FkKCB0ZXh0dXJlICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LCB1bmRlZmluZWQsIG9uRXJyb3IgKTtcblxuXHRcdH1cblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHVybHMubGVuZ3RoOyArKyBpICkge1xuXG5cdFx0XHRsb2FkVGV4dHVyZSggaSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRleHR1cmU7XG5cblx0fSxcblxuXHRzZXRDcm9zc09yaWdpbjogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMuY3Jvc3NPcmlnaW4gPSB2YWx1ZTtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFBhdGg6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLnBhdGggPSB2YWx1ZTtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFRleHR1cmVMb2FkZXIoIG1hbmFnZXIgKSB7XG5cblx0dGhpcy5tYW5hZ2VyID0gKCBtYW5hZ2VyICE9PSB1bmRlZmluZWQgKSA/IG1hbmFnZXIgOiBEZWZhdWx0TG9hZGluZ01hbmFnZXI7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggVGV4dHVyZUxvYWRlci5wcm90b3R5cGUsIHtcblxuXHRsb2FkOiBmdW5jdGlvbiAoIHVybCwgb25Mb2FkLCBvblByb2dyZXNzLCBvbkVycm9yICkge1xuXG5cdFx0dmFyIGxvYWRlciA9IG5ldyBJbWFnZUxvYWRlciggdGhpcy5tYW5hZ2VyICk7XG5cdFx0bG9hZGVyLnNldENyb3NzT3JpZ2luKCB0aGlzLmNyb3NzT3JpZ2luICk7XG5cdFx0bG9hZGVyLnNldFBhdGgoIHRoaXMucGF0aCApO1xuXG5cdFx0dmFyIHRleHR1cmUgPSBuZXcgVGV4dHVyZSgpO1xuXHRcdHRleHR1cmUuaW1hZ2UgPSBsb2FkZXIubG9hZCggdXJsLCBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdC8vIEpQRUdzIGNhbid0IGhhdmUgYW4gYWxwaGEgY2hhbm5lbCwgc28gbWVtb3J5IGNhbiBiZSBzYXZlZCBieSBzdG9yaW5nIHRoZW0gYXMgUkdCLlxuXHRcdFx0dmFyIGlzSlBFRyA9IHVybC5zZWFyY2goIC9cXC4oanBnfGpwZWcpJC8gKSA+IDAgfHwgdXJsLnNlYXJjaCggL15kYXRhXFw6aW1hZ2VcXC9qcGVnLyApID09PSAwO1xuXG5cdFx0XHR0ZXh0dXJlLmZvcm1hdCA9IGlzSlBFRyA/IFJHQkZvcm1hdCA6IFJHQkFGb3JtYXQ7XG5cdFx0XHR0ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCBvbkxvYWQgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRvbkxvYWQoIHRleHR1cmUgKTtcblxuXHRcdFx0fVxuXG5cdFx0fSwgb25Qcm9ncmVzcywgb25FcnJvciApO1xuXG5cdFx0cmV0dXJuIHRleHR1cmU7XG5cblx0fSxcblxuXHRzZXRDcm9zc09yaWdpbjogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMuY3Jvc3NPcmlnaW4gPSB2YWx1ZTtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFBhdGg6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLnBhdGggPSB2YWx1ZTtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBMaWdodCggY29sb3IsIGludGVuc2l0eSApIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0xpZ2h0JztcblxuXHR0aGlzLmNvbG9yID0gbmV3IENvbG9yKCBjb2xvciApO1xuXHR0aGlzLmludGVuc2l0eSA9IGludGVuc2l0eSAhPT0gdW5kZWZpbmVkID8gaW50ZW5zaXR5IDogMTtcblxuXHR0aGlzLnJlY2VpdmVTaGFkb3cgPSB1bmRlZmluZWQ7XG5cbn1cblxuTGlnaHQucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTGlnaHQsXG5cblx0aXNMaWdodDogdHJ1ZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdE9iamVjdDNELnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdFx0dGhpcy5jb2xvci5jb3B5KCBzb3VyY2UuY29sb3IgKTtcblx0XHR0aGlzLmludGVuc2l0eSA9IHNvdXJjZS5pbnRlbnNpdHk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCBtZXRhICkge1xuXG5cdFx0dmFyIGRhdGEgPSBPYmplY3QzRC5wcm90b3R5cGUudG9KU09OLmNhbGwoIHRoaXMsIG1ldGEgKTtcblxuXHRcdGRhdGEub2JqZWN0LmNvbG9yID0gdGhpcy5jb2xvci5nZXRIZXgoKTtcblx0XHRkYXRhLm9iamVjdC5pbnRlbnNpdHkgPSB0aGlzLmludGVuc2l0eTtcblxuXHRcdGlmICggdGhpcy5ncm91bmRDb2xvciAhPT0gdW5kZWZpbmVkICkgZGF0YS5vYmplY3QuZ3JvdW5kQ29sb3IgPSB0aGlzLmdyb3VuZENvbG9yLmdldEhleCgpO1xuXG5cdFx0aWYgKCB0aGlzLmRpc3RhbmNlICE9PSB1bmRlZmluZWQgKSBkYXRhLm9iamVjdC5kaXN0YW5jZSA9IHRoaXMuZGlzdGFuY2U7XG5cdFx0aWYgKCB0aGlzLmFuZ2xlICE9PSB1bmRlZmluZWQgKSBkYXRhLm9iamVjdC5hbmdsZSA9IHRoaXMuYW5nbGU7XG5cdFx0aWYgKCB0aGlzLmRlY2F5ICE9PSB1bmRlZmluZWQgKSBkYXRhLm9iamVjdC5kZWNheSA9IHRoaXMuZGVjYXk7XG5cdFx0aWYgKCB0aGlzLnBlbnVtYnJhICE9PSB1bmRlZmluZWQgKSBkYXRhLm9iamVjdC5wZW51bWJyYSA9IHRoaXMucGVudW1icmE7XG5cblx0XHRpZiAoIHRoaXMuc2hhZG93ICE9PSB1bmRlZmluZWQgKSBkYXRhLm9iamVjdC5zaGFkb3cgPSB0aGlzLnNoYWRvdy50b0pTT04oKTtcblxuXHRcdHJldHVybiBkYXRhO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gSGVtaXNwaGVyZUxpZ2h0KCBza3lDb2xvciwgZ3JvdW5kQ29sb3IsIGludGVuc2l0eSApIHtcblxuXHRMaWdodC5jYWxsKCB0aGlzLCBza3lDb2xvciwgaW50ZW5zaXR5ICk7XG5cblx0dGhpcy50eXBlID0gJ0hlbWlzcGhlcmVMaWdodCc7XG5cblx0dGhpcy5jYXN0U2hhZG93ID0gdW5kZWZpbmVkO1xuXG5cdHRoaXMucG9zaXRpb24uY29weSggT2JqZWN0M0QuRGVmYXVsdFVwICk7XG5cdHRoaXMudXBkYXRlTWF0cml4KCk7XG5cblx0dGhpcy5ncm91bmRDb2xvciA9IG5ldyBDb2xvciggZ3JvdW5kQ29sb3IgKTtcblxufVxuXG5IZW1pc3BoZXJlTGlnaHQucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggTGlnaHQucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogSGVtaXNwaGVyZUxpZ2h0LFxuXG5cdGlzSGVtaXNwaGVyZUxpZ2h0OiB0cnVlLFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0TGlnaHQucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLmdyb3VuZENvbG9yLmNvcHkoIHNvdXJjZS5ncm91bmRDb2xvciApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBMaWdodFNoYWRvdyggY2FtZXJhICkge1xuXG5cdHRoaXMuY2FtZXJhID0gY2FtZXJhO1xuXG5cdHRoaXMuYmlhcyA9IDA7XG5cdHRoaXMucmFkaXVzID0gMTtcblxuXHR0aGlzLm1hcFNpemUgPSBuZXcgVmVjdG9yMiggNTEyLCA1MTIgKTtcblxuXHR0aGlzLm1hcCA9IG51bGw7XG5cdHRoaXMubWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBMaWdodFNoYWRvdy5wcm90b3R5cGUsIHtcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdHRoaXMuY2FtZXJhID0gc291cmNlLmNhbWVyYS5jbG9uZSgpO1xuXG5cdFx0dGhpcy5iaWFzID0gc291cmNlLmJpYXM7XG5cdFx0dGhpcy5yYWRpdXMgPSBzb3VyY2UucmFkaXVzO1xuXG5cdFx0dGhpcy5tYXBTaXplLmNvcHkoIHNvdXJjZS5tYXBTaXplICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KCB0aGlzICk7XG5cblx0fSxcblxuXHR0b0pTT046IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBvYmplY3QgPSB7fTtcblxuXHRcdGlmICggdGhpcy5iaWFzICE9PSAwICkgb2JqZWN0LmJpYXMgPSB0aGlzLmJpYXM7XG5cdFx0aWYgKCB0aGlzLnJhZGl1cyAhPT0gMSApIG9iamVjdC5yYWRpdXMgPSB0aGlzLnJhZGl1cztcblx0XHRpZiAoIHRoaXMubWFwU2l6ZS54ICE9PSA1MTIgfHwgdGhpcy5tYXBTaXplLnkgIT09IDUxMiApIG9iamVjdC5tYXBTaXplID0gdGhpcy5tYXBTaXplLnRvQXJyYXkoKTtcblxuXHRcdG9iamVjdC5jYW1lcmEgPSB0aGlzLmNhbWVyYS50b0pTT04oIGZhbHNlICkub2JqZWN0O1xuXHRcdGRlbGV0ZSBvYmplY3QuY2FtZXJhLm1hdHJpeDtcblxuXHRcdHJldHVybiBvYmplY3Q7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBTcG90TGlnaHRTaGFkb3coKSB7XG5cblx0TGlnaHRTaGFkb3cuY2FsbCggdGhpcywgbmV3IFBlcnNwZWN0aXZlQ2FtZXJhKCA1MCwgMSwgMC41LCA1MDAgKSApO1xuXG59XG5cblNwb3RMaWdodFNoYWRvdy5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBMaWdodFNoYWRvdy5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBTcG90TGlnaHRTaGFkb3csXG5cblx0aXNTcG90TGlnaHRTaGFkb3c6IHRydWUsXG5cblx0dXBkYXRlOiBmdW5jdGlvbiAoIGxpZ2h0ICkge1xuXG5cdFx0dmFyIGNhbWVyYSA9IHRoaXMuY2FtZXJhO1xuXG5cdFx0dmFyIGZvdiA9IF9NYXRoLlJBRDJERUcgKiAyICogbGlnaHQuYW5nbGU7XG5cdFx0dmFyIGFzcGVjdCA9IHRoaXMubWFwU2l6ZS53aWR0aCAvIHRoaXMubWFwU2l6ZS5oZWlnaHQ7XG5cdFx0dmFyIGZhciA9IGxpZ2h0LmRpc3RhbmNlIHx8IGNhbWVyYS5mYXI7XG5cblx0XHRpZiAoIGZvdiAhPT0gY2FtZXJhLmZvdiB8fCBhc3BlY3QgIT09IGNhbWVyYS5hc3BlY3QgfHwgZmFyICE9PSBjYW1lcmEuZmFyICkge1xuXG5cdFx0XHRjYW1lcmEuZm92ID0gZm92O1xuXHRcdFx0Y2FtZXJhLmFzcGVjdCA9IGFzcGVjdDtcblx0XHRcdGNhbWVyYS5mYXIgPSBmYXI7XG5cdFx0XHRjYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gU3BvdExpZ2h0KCBjb2xvciwgaW50ZW5zaXR5LCBkaXN0YW5jZSwgYW5nbGUsIHBlbnVtYnJhLCBkZWNheSApIHtcblxuXHRMaWdodC5jYWxsKCB0aGlzLCBjb2xvciwgaW50ZW5zaXR5ICk7XG5cblx0dGhpcy50eXBlID0gJ1Nwb3RMaWdodCc7XG5cblx0dGhpcy5wb3NpdGlvbi5jb3B5KCBPYmplY3QzRC5EZWZhdWx0VXAgKTtcblx0dGhpcy51cGRhdGVNYXRyaXgoKTtcblxuXHR0aGlzLnRhcmdldCA9IG5ldyBPYmplY3QzRCgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggdGhpcywgJ3Bvd2VyJywge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXHRcdFx0Ly8gaW50ZW5zaXR5ID0gcG93ZXIgcGVyIHNvbGlkIGFuZ2xlLlxuXHRcdFx0Ly8gcmVmOiBlcXVhdGlvbiAoMTcpIGZyb20gaHR0cDovL3d3dy5mcm9zdGJpdGUuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE0LzExL2NvdXJzZV9ub3Rlc19tb3ZpbmdfZnJvc3RiaXRlX3RvX3Bici5wZGZcblx0XHRcdHJldHVybiB0aGlzLmludGVuc2l0eSAqIE1hdGguUEk7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uICggcG93ZXIgKSB7XG5cdFx0XHQvLyBpbnRlbnNpdHkgPSBwb3dlciBwZXIgc29saWQgYW5nbGUuXG5cdFx0XHQvLyByZWY6IGVxdWF0aW9uICgxNykgZnJvbSBodHRwOi8vd3d3LmZyb3N0Yml0ZS5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMTQvMTEvY291cnNlX25vdGVzX21vdmluZ19mcm9zdGJpdGVfdG9fcGJyLnBkZlxuXHRcdFx0dGhpcy5pbnRlbnNpdHkgPSBwb3dlciAvIE1hdGguUEk7XG5cdFx0fVxuXHR9ICk7XG5cblx0dGhpcy5kaXN0YW5jZSA9ICggZGlzdGFuY2UgIT09IHVuZGVmaW5lZCApID8gZGlzdGFuY2UgOiAwO1xuXHR0aGlzLmFuZ2xlID0gKCBhbmdsZSAhPT0gdW5kZWZpbmVkICkgPyBhbmdsZSA6IE1hdGguUEkgLyAzO1xuXHR0aGlzLnBlbnVtYnJhID0gKCBwZW51bWJyYSAhPT0gdW5kZWZpbmVkICkgPyBwZW51bWJyYSA6IDA7XG5cdHRoaXMuZGVjYXkgPSAoIGRlY2F5ICE9PSB1bmRlZmluZWQgKSA/IGRlY2F5IDogMTtcdC8vIGZvciBwaHlzaWNhbGx5IGNvcnJlY3QgbGlnaHRzLCBzaG91bGQgYmUgMi5cblxuXHR0aGlzLnNoYWRvdyA9IG5ldyBTcG90TGlnaHRTaGFkb3coKTtcblxufVxuXG5TcG90TGlnaHQucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggTGlnaHQucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogU3BvdExpZ2h0LFxuXG5cdGlzU3BvdExpZ2h0OiB0cnVlLFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0TGlnaHQucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLmRpc3RhbmNlID0gc291cmNlLmRpc3RhbmNlO1xuXHRcdHRoaXMuYW5nbGUgPSBzb3VyY2UuYW5nbGU7XG5cdFx0dGhpcy5wZW51bWJyYSA9IHNvdXJjZS5wZW51bWJyYTtcblx0XHR0aGlzLmRlY2F5ID0gc291cmNlLmRlY2F5O1xuXG5cdFx0dGhpcy50YXJnZXQgPSBzb3VyY2UudGFyZ2V0LmNsb25lKCk7XG5cblx0XHR0aGlzLnNoYWRvdyA9IHNvdXJjZS5zaGFkb3cuY2xvbmUoKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuXG5mdW5jdGlvbiBQb2ludExpZ2h0KCBjb2xvciwgaW50ZW5zaXR5LCBkaXN0YW5jZSwgZGVjYXkgKSB7XG5cblx0TGlnaHQuY2FsbCggdGhpcywgY29sb3IsIGludGVuc2l0eSApO1xuXG5cdHRoaXMudHlwZSA9ICdQb2ludExpZ2h0JztcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIHRoaXMsICdwb3dlcicsIHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdC8vIGludGVuc2l0eSA9IHBvd2VyIHBlciBzb2xpZCBhbmdsZS5cblx0XHRcdC8vIHJlZjogZXF1YXRpb24gKDE1KSBmcm9tIGh0dHA6Ly93d3cuZnJvc3RiaXRlLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNC8xMS9jb3Vyc2Vfbm90ZXNfbW92aW5nX2Zyb3N0Yml0ZV90b19wYnIucGRmXG5cdFx0XHRyZXR1cm4gdGhpcy5pbnRlbnNpdHkgKiA0ICogTWF0aC5QSTtcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHBvd2VyICkge1xuXHRcdFx0Ly8gaW50ZW5zaXR5ID0gcG93ZXIgcGVyIHNvbGlkIGFuZ2xlLlxuXHRcdFx0Ly8gcmVmOiBlcXVhdGlvbiAoMTUpIGZyb20gaHR0cDovL3d3dy5mcm9zdGJpdGUuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE0LzExL2NvdXJzZV9ub3Rlc19tb3ZpbmdfZnJvc3RiaXRlX3RvX3Bici5wZGZcblx0XHRcdHRoaXMuaW50ZW5zaXR5ID0gcG93ZXIgLyAoIDQgKiBNYXRoLlBJICk7XG5cdFx0fVxuXHR9ICk7XG5cblx0dGhpcy5kaXN0YW5jZSA9ICggZGlzdGFuY2UgIT09IHVuZGVmaW5lZCApID8gZGlzdGFuY2UgOiAwO1xuXHR0aGlzLmRlY2F5ID0gKCBkZWNheSAhPT0gdW5kZWZpbmVkICkgPyBkZWNheSA6IDE7XHQvLyBmb3IgcGh5c2ljYWxseSBjb3JyZWN0IGxpZ2h0cywgc2hvdWxkIGJlIDIuXG5cblx0dGhpcy5zaGFkb3cgPSBuZXcgTGlnaHRTaGFkb3coIG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSggOTAsIDEsIDAuNSwgNTAwICkgKTtcblxufVxuXG5Qb2ludExpZ2h0LnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIExpZ2h0LnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IFBvaW50TGlnaHQsXG5cblx0aXNQb2ludExpZ2h0OiB0cnVlLFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0TGlnaHQucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLmRpc3RhbmNlID0gc291cmNlLmRpc3RhbmNlO1xuXHRcdHRoaXMuZGVjYXkgPSBzb3VyY2UuZGVjYXk7XG5cblx0XHR0aGlzLnNoYWRvdyA9IHNvdXJjZS5zaGFkb3cuY2xvbmUoKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gRGlyZWN0aW9uYWxMaWdodFNoYWRvdyggKSB7XG5cblx0TGlnaHRTaGFkb3cuY2FsbCggdGhpcywgbmV3IE9ydGhvZ3JhcGhpY0NhbWVyYSggLSA1LCA1LCA1LCAtIDUsIDAuNSwgNTAwICkgKTtcblxufVxuXG5EaXJlY3Rpb25hbExpZ2h0U2hhZG93LnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIExpZ2h0U2hhZG93LnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IERpcmVjdGlvbmFsTGlnaHRTaGFkb3dcblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICovXG5cbmZ1bmN0aW9uIERpcmVjdGlvbmFsTGlnaHQoIGNvbG9yLCBpbnRlbnNpdHkgKSB7XG5cblx0TGlnaHQuY2FsbCggdGhpcywgY29sb3IsIGludGVuc2l0eSApO1xuXG5cdHRoaXMudHlwZSA9ICdEaXJlY3Rpb25hbExpZ2h0JztcblxuXHR0aGlzLnBvc2l0aW9uLmNvcHkoIE9iamVjdDNELkRlZmF1bHRVcCApO1xuXHR0aGlzLnVwZGF0ZU1hdHJpeCgpO1xuXG5cdHRoaXMudGFyZ2V0ID0gbmV3IE9iamVjdDNEKCk7XG5cblx0dGhpcy5zaGFkb3cgPSBuZXcgRGlyZWN0aW9uYWxMaWdodFNoYWRvdygpO1xuXG59XG5cbkRpcmVjdGlvbmFsTGlnaHQucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggTGlnaHQucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogRGlyZWN0aW9uYWxMaWdodCxcblxuXHRpc0RpcmVjdGlvbmFsTGlnaHQ6IHRydWUsXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHRMaWdodC5wcm90b3R5cGUuY29weS5jYWxsKCB0aGlzLCBzb3VyY2UgKTtcblxuXHRcdHRoaXMudGFyZ2V0ID0gc291cmNlLnRhcmdldC5jbG9uZSgpO1xuXG5cdFx0dGhpcy5zaGFkb3cgPSBzb3VyY2Uuc2hhZG93LmNsb25lKCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEFtYmllbnRMaWdodCggY29sb3IsIGludGVuc2l0eSApIHtcblxuXHRMaWdodC5jYWxsKCB0aGlzLCBjb2xvciwgaW50ZW5zaXR5ICk7XG5cblx0dGhpcy50eXBlID0gJ0FtYmllbnRMaWdodCc7XG5cblx0dGhpcy5jYXN0U2hhZG93ID0gdW5kZWZpbmVkO1xuXG59XG5cbkFtYmllbnRMaWdodC5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBMaWdodC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBBbWJpZW50TGlnaHQsXG5cblx0aXNBbWJpZW50TGlnaHQ6IHRydWVcblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYWJlbG5hdGlvbiAvIGh0dHA6Ly9naXRodWIuY29tL2FiZWxuYXRpb25cbiAqL1xuXG5mdW5jdGlvbiBSZWN0QXJlYUxpZ2h0KCBjb2xvciwgaW50ZW5zaXR5LCB3aWR0aCwgaGVpZ2h0ICkge1xuXG5cdExpZ2h0LmNhbGwoIHRoaXMsIGNvbG9yLCBpbnRlbnNpdHkgKTtcblxuXHR0aGlzLnR5cGUgPSAnUmVjdEFyZWFMaWdodCc7XG5cblx0dGhpcy5wb3NpdGlvbi5zZXQoIDAsIDEsIDAgKTtcblx0dGhpcy51cGRhdGVNYXRyaXgoKTtcblxuXHR0aGlzLndpZHRoID0gKCB3aWR0aCAhPT0gdW5kZWZpbmVkICkgPyB3aWR0aCA6IDEwO1xuXHR0aGlzLmhlaWdodCA9ICggaGVpZ2h0ICE9PSB1bmRlZmluZWQgKSA/IGhlaWdodCA6IDEwO1xuXG5cdC8vIFRPRE8gKGFiZWxuYXRpb24pOiBkaXN0YW5jZS9kZWNheVxuXG5cdC8vIFRPRE8gKGFiZWxuYXRpb24pOiB1cGRhdGUgbWV0aG9kIGZvciBSZWN0QXJlYUxpZ2h0IHRvIHVwZGF0ZSB0cmFuc2Zvcm0gdG8gbG9va2F0IHRhcmdldFxuXG5cdC8vIFRPRE8gKGFiZWxuYXRpb24pOiBzaGFkb3dzXG5cbn1cblxuLy8gVE9ETyAoYWJlbG5hdGlvbik6IFJlY3RBcmVhTGlnaHQgdXBkYXRlIHdoZW4gbGlnaHQgc2hhcGUgaXMgY2hhbmdlZFxuUmVjdEFyZWFMaWdodC5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBMaWdodC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBSZWN0QXJlYUxpZ2h0LFxuXG5cdGlzUmVjdEFyZWFMaWdodDogdHJ1ZSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIHNvdXJjZSApIHtcblxuXHRcdExpZ2h0LnByb3RvdHlwZS5jb3B5LmNhbGwoIHRoaXMsIHNvdXJjZSApO1xuXG5cdFx0dGhpcy53aWR0aCA9IHNvdXJjZS53aWR0aDtcblx0XHR0aGlzLmhlaWdodCA9IHNvdXJjZS5oZWlnaHQ7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCBtZXRhICkge1xuXG5cdFx0dmFyIGRhdGEgPSBMaWdodC5wcm90b3R5cGUudG9KU09OLmNhbGwoIHRoaXMsIG1ldGEgKTtcblxuXHRcdGRhdGEub2JqZWN0LndpZHRoID0gdGhpcy53aWR0aDtcblx0XHRkYXRhLm9iamVjdC5oZWlnaHQgPSB0aGlzLmhlaWdodDtcblxuXHRcdHJldHVybiBkYXRhO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgdHNjaHdcbiAqIEBhdXRob3IgQmVuIEhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW8vXG4gKiBAYXV0aG9yIERhdmlkIFNhcm5vIC8gaHR0cDovL2xpZ2h0aGF1cy51cy9cbiAqL1xuXG52YXIgQW5pbWF0aW9uVXRpbHMgPSB7XG5cblx0Ly8gc2FtZSBhcyBBcnJheS5wcm90b3R5cGUuc2xpY2UsIGJ1dCBhbHNvIHdvcmtzIG9uIHR5cGVkIGFycmF5c1xuXHRhcnJheVNsaWNlOiBmdW5jdGlvbiAoIGFycmF5LCBmcm9tLCB0byApIHtcblxuXHRcdGlmICggQW5pbWF0aW9uVXRpbHMuaXNUeXBlZEFycmF5KCBhcnJheSApICkge1xuXG5cdFx0XHQvLyBpbiBpb3M5IGFycmF5LnN1YmFycmF5KGZyb20sIHVuZGVmaW5lZCkgd2lsbCByZXR1cm4gZW1wdHkgYXJyYXlcblx0XHRcdC8vIGJ1dCBhcnJheS5zdWJhcnJheShmcm9tKSBvciBhcnJheS5zdWJhcnJheShmcm9tLCBsZW4pIGlzIGNvcnJlY3Rcblx0XHRcdHJldHVybiBuZXcgYXJyYXkuY29uc3RydWN0b3IoIGFycmF5LnN1YmFycmF5KCBmcm9tLCB0byAhPT0gdW5kZWZpbmVkID8gdG8gOiBhcnJheS5sZW5ndGggKSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFycmF5LnNsaWNlKCBmcm9tLCB0byApO1xuXG5cdH0sXG5cblx0Ly8gY29udmVydHMgYW4gYXJyYXkgdG8gYSBzcGVjaWZpYyB0eXBlXG5cdGNvbnZlcnRBcnJheTogZnVuY3Rpb24gKCBhcnJheSwgdHlwZSwgZm9yY2VDbG9uZSApIHtcblxuXHRcdGlmICggISBhcnJheSB8fCAvLyBsZXQgJ3VuZGVmaW5lZCcgYW5kICdudWxsJyBwYXNzXG5cdFx0XHRcdCEgZm9yY2VDbG9uZSAmJiBhcnJheS5jb25zdHJ1Y3RvciA9PT0gdHlwZSApIHJldHVybiBhcnJheTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUuQllURVNfUEVSX0VMRU1FTlQgPT09ICdudW1iZXInICkge1xuXG5cdFx0XHRyZXR1cm4gbmV3IHR5cGUoIGFycmF5ICk7IC8vIGNyZWF0ZSB0eXBlZCBhcnJheVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBhcnJheSApOyAvLyBjcmVhdGUgQXJyYXlcblxuXHR9LFxuXG5cdGlzVHlwZWRBcnJheTogZnVuY3Rpb24gKCBvYmplY3QgKSB7XG5cblx0XHRyZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KCBvYmplY3QgKSAmJlxuXHRcdFx0XHQhICggb2JqZWN0IGluc3RhbmNlb2YgRGF0YVZpZXcgKTtcblxuXHR9LFxuXG5cdC8vIHJldHVybnMgYW4gYXJyYXkgYnkgd2hpY2ggdGltZXMgYW5kIHZhbHVlcyBjYW4gYmUgc29ydGVkXG5cdGdldEtleWZyYW1lT3JkZXI6IGZ1bmN0aW9uICggdGltZXMgKSB7XG5cblx0XHRmdW5jdGlvbiBjb21wYXJlVGltZSggaSwgaiApIHtcblxuXHRcdFx0cmV0dXJuIHRpbWVzWyBpIF0gLSB0aW1lc1sgaiBdO1xuXG5cdFx0fVxuXG5cdFx0dmFyIG4gPSB0aW1lcy5sZW5ndGg7XG5cdFx0dmFyIHJlc3VsdCA9IG5ldyBBcnJheSggbiApO1xuXHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gbjsgKysgaSApIHJlc3VsdFsgaSBdID0gaTtcblxuXHRcdHJlc3VsdC5zb3J0KCBjb21wYXJlVGltZSApO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblxuXHR9LFxuXG5cdC8vIHVzZXMgdGhlIGFycmF5IHByZXZpb3VzbHkgcmV0dXJuZWQgYnkgJ2dldEtleWZyYW1lT3JkZXInIHRvIHNvcnQgZGF0YVxuXHRzb3J0ZWRBcnJheTogZnVuY3Rpb24gKCB2YWx1ZXMsIHN0cmlkZSwgb3JkZXIgKSB7XG5cblx0XHR2YXIgblZhbHVlcyA9IHZhbHVlcy5sZW5ndGg7XG5cdFx0dmFyIHJlc3VsdCA9IG5ldyB2YWx1ZXMuY29uc3RydWN0b3IoIG5WYWx1ZXMgKTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgZHN0T2Zmc2V0ID0gMDsgZHN0T2Zmc2V0ICE9PSBuVmFsdWVzOyArKyBpICkge1xuXG5cdFx0XHR2YXIgc3JjT2Zmc2V0ID0gb3JkZXJbIGkgXSAqIHN0cmlkZTtcblxuXHRcdFx0Zm9yICggdmFyIGogPSAwOyBqICE9PSBzdHJpZGU7ICsrIGogKSB7XG5cblx0XHRcdFx0cmVzdWx0WyBkc3RPZmZzZXQgKysgXSA9IHZhbHVlc1sgc3JjT2Zmc2V0ICsgaiBdO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdH0sXG5cblx0Ly8gZnVuY3Rpb24gZm9yIHBhcnNpbmcgQU9TIGtleWZyYW1lIGZvcm1hdHNcblx0ZmxhdHRlbkpTT046IGZ1bmN0aW9uICgganNvbktleXMsIHRpbWVzLCB2YWx1ZXMsIHZhbHVlUHJvcGVydHlOYW1lICkge1xuXG5cdFx0dmFyIGkgPSAxLCBrZXkgPSBqc29uS2V5c1sgMCBdO1xuXG5cdFx0d2hpbGUgKCBrZXkgIT09IHVuZGVmaW5lZCAmJiBrZXlbIHZhbHVlUHJvcGVydHlOYW1lIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0a2V5ID0ganNvbktleXNbIGkgKysgXTtcblxuXHRcdH1cblxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSByZXR1cm47IC8vIG5vIGRhdGFcblxuXHRcdHZhciB2YWx1ZSA9IGtleVsgdmFsdWVQcm9wZXJ0eU5hbWUgXTtcblx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgKSByZXR1cm47IC8vIG5vIGRhdGFcblxuXHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblxuXHRcdFx0ZG8ge1xuXG5cdFx0XHRcdHZhbHVlID0ga2V5WyB2YWx1ZVByb3BlcnR5TmFtZSBdO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdHRpbWVzLnB1c2goIGtleS50aW1lICk7XG5cdFx0XHRcdFx0dmFsdWVzLnB1c2guYXBwbHkoIHZhbHVlcywgdmFsdWUgKTsgLy8gcHVzaCBhbGwgZWxlbWVudHNcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0a2V5ID0ganNvbktleXNbIGkgKysgXTtcblxuXHRcdFx0fSB3aGlsZSAoIGtleSAhPT0gdW5kZWZpbmVkICk7XG5cblx0XHR9IGVsc2UgaWYgKCB2YWx1ZS50b0FycmF5ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIC4uLmFzc3VtZSBUSFJFRS5NYXRoLWlzaFxuXG5cdFx0XHRkbyB7XG5cblx0XHRcdFx0dmFsdWUgPSBrZXlbIHZhbHVlUHJvcGVydHlOYW1lIF07XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0dGltZXMucHVzaCgga2V5LnRpbWUgKTtcblx0XHRcdFx0XHR2YWx1ZS50b0FycmF5KCB2YWx1ZXMsIHZhbHVlcy5sZW5ndGggKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0a2V5ID0ganNvbktleXNbIGkgKysgXTtcblxuXHRcdFx0fSB3aGlsZSAoIGtleSAhPT0gdW5kZWZpbmVkICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBvdGhlcndpc2UgcHVzaCBhcy1pc1xuXG5cdFx0XHRkbyB7XG5cblx0XHRcdFx0dmFsdWUgPSBrZXlbIHZhbHVlUHJvcGVydHlOYW1lIF07XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0dGltZXMucHVzaCgga2V5LnRpbWUgKTtcblx0XHRcdFx0XHR2YWx1ZXMucHVzaCggdmFsdWUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0a2V5ID0ganNvbktleXNbIGkgKysgXTtcblxuXHRcdFx0fSB3aGlsZSAoIGtleSAhPT0gdW5kZWZpbmVkICk7XG5cblx0XHR9XG5cblx0fVxuXG59O1xuXG4vKipcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3Mgb2YgaW50ZXJwb2xhbnRzIG92ZXIgcGFyYW1ldHJpYyBzYW1wbGVzLlxuICpcbiAqIFRoZSBwYXJhbWV0ZXIgZG9tYWluIGlzIG9uZSBkaW1lbnNpb25hbCwgdHlwaWNhbGx5IHRoZSB0aW1lIG9yIGEgcGF0aFxuICogYWxvbmcgYSBjdXJ2ZSBkZWZpbmVkIGJ5IHRoZSBkYXRhLlxuICpcbiAqIFRoZSBzYW1wbGUgdmFsdWVzIGNhbiBoYXZlIGFueSBkaW1lbnNpb25hbGl0eSBhbmQgZGVyaXZlZCBjbGFzc2VzIG1heVxuICogYXBwbHkgc3BlY2lhbCBpbnRlcnByZXRhdGlvbnMgdG8gdGhlIGRhdGEuXG4gKlxuICogVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgaW50ZXJ2YWwgc2VlayBpbiBhIFRlbXBsYXRlIE1ldGhvZCwgZGVmZXJyaW5nXG4gKiB0aGUgYWN0dWFsIGludGVycG9sYXRpb24gdG8gZGVyaXZlZCBjbGFzc2VzLlxuICpcbiAqIFRpbWUgY29tcGxleGl0eSBpcyBPKDEpIGZvciBsaW5lYXIgYWNjZXNzIGNyb3NzaW5nIGF0IG1vc3QgdHdvIHBvaW50c1xuICogYW5kIE8obG9nIE4pIGZvciByYW5kb20gYWNjZXNzLCB3aGVyZSBOIGlzIHRoZSBudW1iZXIgb2YgcG9zaXRpb25zLlxuICpcbiAqIFJlZmVyZW5jZXM6XG4gKlxuICogXHRcdGh0dHA6Ly93d3cub29kZXNpZ24uY29tL3RlbXBsYXRlLW1ldGhvZC1wYXR0ZXJuLmh0bWxcbiAqXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gSW50ZXJwb2xhbnQoIHBhcmFtZXRlclBvc2l0aW9ucywgc2FtcGxlVmFsdWVzLCBzYW1wbGVTaXplLCByZXN1bHRCdWZmZXIgKSB7XG5cblx0dGhpcy5wYXJhbWV0ZXJQb3NpdGlvbnMgPSBwYXJhbWV0ZXJQb3NpdGlvbnM7XG5cdHRoaXMuX2NhY2hlZEluZGV4ID0gMDtcblxuXHR0aGlzLnJlc3VsdEJ1ZmZlciA9IHJlc3VsdEJ1ZmZlciAhPT0gdW5kZWZpbmVkID9cblx0XHRcdHJlc3VsdEJ1ZmZlciA6IG5ldyBzYW1wbGVWYWx1ZXMuY29uc3RydWN0b3IoIHNhbXBsZVNpemUgKTtcblx0dGhpcy5zYW1wbGVWYWx1ZXMgPSBzYW1wbGVWYWx1ZXM7XG5cdHRoaXMudmFsdWVTaXplID0gc2FtcGxlU2l6ZTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBJbnRlcnBvbGFudC5wcm90b3R5cGUsIHtcblxuXHRldmFsdWF0ZTogZnVuY3Rpb24oIHQgKSB7XG5cblx0XHR2YXIgcHAgPSB0aGlzLnBhcmFtZXRlclBvc2l0aW9ucyxcblx0XHRcdGkxID0gdGhpcy5fY2FjaGVkSW5kZXgsXG5cblx0XHRcdHQxID0gcHBbICAgaTEgICBdLFxuXHRcdFx0dDAgPSBwcFsgaTEgLSAxIF07XG5cblx0XHR2YWxpZGF0ZV9pbnRlcnZhbDoge1xuXG5cdFx0XHRzZWVrOiB7XG5cblx0XHRcdFx0dmFyIHJpZ2h0O1xuXG5cdFx0XHRcdGxpbmVhcl9zY2FuOiB7XG5cdFx0XHRcdFx0Ly8tIFNlZSBodHRwOi8vanNwZXJmLmNvbS9jb21wYXJpc29uLXRvLXVuZGVmaW5lZC8zXG5cdFx0XHRcdFx0Ly8tIHNsb3dlciBjb2RlOlxuXHRcdFx0XHRcdC8vLVxuXHRcdFx0XHRcdC8vLSBcdFx0XHRcdGlmICggdCA+PSB0MSB8fCB0MSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGZvcndhcmRfc2NhbjogaWYgKCAhICggdCA8IHQxICkgKSB7XG5cblx0XHRcdFx0XHRcdGZvciAoIHZhciBnaXZlVXBBdCA9IGkxICsgMjsgOykge1xuXG5cdFx0XHRcdFx0XHRcdGlmICggdDEgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGlmICggdCA8IHQwICkgYnJlYWsgZm9yd2FyZF9zY2FuO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gYWZ0ZXIgZW5kXG5cblx0XHRcdFx0XHRcdFx0XHRpMSA9IHBwLmxlbmd0aDtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9jYWNoZWRJbmRleCA9IGkxO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0aGlzLmFmdGVyRW5kXyggaTEgLSAxLCB0LCB0MCApO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAoIGkxID09PSBnaXZlVXBBdCApIGJyZWFrOyAvLyB0aGlzIGxvb3BcblxuXHRcdFx0XHRcdFx0XHR0MCA9IHQxO1xuXHRcdFx0XHRcdFx0XHR0MSA9IHBwWyArKyBpMSBdO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggdCA8IHQxICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gd2UgaGF2ZSBhcnJpdmVkIGF0IHRoZSBzb3VnaHQgaW50ZXJ2YWxcblx0XHRcdFx0XHRcdFx0XHRicmVhayBzZWVrO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBwcmVwYXJlIGJpbmFyeSBzZWFyY2ggb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGluZGV4XG5cdFx0XHRcdFx0XHRyaWdodCA9IHBwLmxlbmd0aDtcblx0XHRcdFx0XHRcdGJyZWFrIGxpbmVhcl9zY2FuO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8tIHNsb3dlciBjb2RlOlxuXHRcdFx0XHRcdC8vLVx0XHRcdFx0XHRpZiAoIHQgPCB0MCB8fCB0MCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGlmICggISAoIHQgPj0gdDAgKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gbG9vcGluZz9cblxuXHRcdFx0XHRcdFx0dmFyIHQxZ2xvYmFsID0gcHBbIDEgXTtcblxuXHRcdFx0XHRcdFx0aWYgKCB0IDwgdDFnbG9iYWwgKSB7XG5cblx0XHRcdFx0XHRcdFx0aTEgPSAyOyAvLyArIDEsIHVzaW5nIHRoZSBzY2FuIGZvciB0aGUgZGV0YWlsc1xuXHRcdFx0XHRcdFx0XHR0MCA9IHQxZ2xvYmFsO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIGxpbmVhciByZXZlcnNlIHNjYW5cblxuXHRcdFx0XHRcdFx0Zm9yICggdmFyIGdpdmVVcEF0ID0gaTEgLSAyOyA7KSB7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCB0MCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gYmVmb3JlIHN0YXJ0XG5cblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9jYWNoZWRJbmRleCA9IDA7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRoaXMuYmVmb3JlU3RhcnRfKCAwLCB0LCB0MSApO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAoIGkxID09PSBnaXZlVXBBdCApIGJyZWFrOyAvLyB0aGlzIGxvb3BcblxuXHRcdFx0XHRcdFx0XHR0MSA9IHQwO1xuXHRcdFx0XHRcdFx0XHR0MCA9IHBwWyAtLSBpMSAtIDEgXTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHQgPj0gdDAgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyB3ZSBoYXZlIGFycml2ZWQgYXQgdGhlIHNvdWdodCBpbnRlcnZhbFxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrIHNlZWs7XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIHByZXBhcmUgYmluYXJ5IHNlYXJjaCBvbiB0aGUgbGVmdCBzaWRlIG9mIHRoZSBpbmRleFxuXHRcdFx0XHRcdFx0cmlnaHQgPSBpMTtcblx0XHRcdFx0XHRcdGkxID0gMDtcblx0XHRcdFx0XHRcdGJyZWFrIGxpbmVhcl9zY2FuO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gdGhlIGludGVydmFsIGlzIHZhbGlkXG5cblx0XHRcdFx0XHRicmVhayB2YWxpZGF0ZV9pbnRlcnZhbDtcblxuXHRcdFx0XHR9IC8vIGxpbmVhciBzY2FuXG5cblx0XHRcdFx0Ly8gYmluYXJ5IHNlYXJjaFxuXG5cdFx0XHRcdHdoaWxlICggaTEgPCByaWdodCApIHtcblxuXHRcdFx0XHRcdHZhciBtaWQgPSAoIGkxICsgcmlnaHQgKSA+Pj4gMTtcblxuXHRcdFx0XHRcdGlmICggdCA8IHBwWyBtaWQgXSApIHtcblxuXHRcdFx0XHRcdFx0cmlnaHQgPSBtaWQ7XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRpMSA9IG1pZCArIDE7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHQxID0gcHBbICAgaTEgICBdO1xuXHRcdFx0XHR0MCA9IHBwWyBpMSAtIDEgXTtcblxuXHRcdFx0XHQvLyBjaGVjayBib3VuZGFyeSBjYXNlcywgYWdhaW5cblxuXHRcdFx0XHRpZiAoIHQwID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHR0aGlzLl9jYWNoZWRJbmRleCA9IDA7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuYmVmb3JlU3RhcnRfKCAwLCB0LCB0MSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHQxID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRpMSA9IHBwLmxlbmd0aDtcblx0XHRcdFx0XHR0aGlzLl9jYWNoZWRJbmRleCA9IGkxO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLmFmdGVyRW5kXyggaTEgLSAxLCB0MCwgdCApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSAvLyBzZWVrXG5cblx0XHRcdHRoaXMuX2NhY2hlZEluZGV4ID0gaTE7XG5cblx0XHRcdHRoaXMuaW50ZXJ2YWxDaGFuZ2VkXyggaTEsIHQwLCB0MSApO1xuXG5cdFx0fSAvLyB2YWxpZGF0ZV9pbnRlcnZhbFxuXG5cdFx0cmV0dXJuIHRoaXMuaW50ZXJwb2xhdGVfKCBpMSwgdDAsIHQsIHQxICk7XG5cblx0fSxcblxuXHRzZXR0aW5nczogbnVsbCwgLy8gb3B0aW9uYWwsIHN1YmNsYXNzLXNwZWNpZmljIHNldHRpbmdzIHN0cnVjdHVyZVxuXHQvLyBOb3RlOiBUaGUgaW5kaXJlY3Rpb24gYWxsb3dzIGNlbnRyYWwgY29udHJvbCBvZiBtYW55IGludGVycG9sYW50cy5cblxuXHQvLyAtLS0gUHJvdGVjdGVkIGludGVyZmFjZVxuXG5cdERlZmF1bHRTZXR0aW5nc186IHt9LFxuXG5cdGdldFNldHRpbmdzXzogZnVuY3Rpb24oKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5zZXR0aW5ncyB8fCB0aGlzLkRlZmF1bHRTZXR0aW5nc187XG5cblx0fSxcblxuXHRjb3B5U2FtcGxlVmFsdWVfOiBmdW5jdGlvbiggaW5kZXggKSB7XG5cblx0XHQvLyBjb3BpZXMgYSBzYW1wbGUgdmFsdWUgdG8gdGhlIHJlc3VsdCBidWZmZXJcblxuXHRcdHZhciByZXN1bHQgPSB0aGlzLnJlc3VsdEJ1ZmZlcixcblx0XHRcdHZhbHVlcyA9IHRoaXMuc2FtcGxlVmFsdWVzLFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cdFx0XHRvZmZzZXQgPSBpbmRleCAqIHN0cmlkZTtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gc3RyaWRlOyArKyBpICkge1xuXG5cdFx0XHRyZXN1bHRbIGkgXSA9IHZhbHVlc1sgb2Zmc2V0ICsgaSBdO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblxuXHR9LFxuXG5cdC8vIFRlbXBsYXRlIG1ldGhvZHMgZm9yIGRlcml2ZWQgY2xhc3NlczpcblxuXHRpbnRlcnBvbGF0ZV86IGZ1bmN0aW9uKCBpMSwgdDAsIHQsIHQxICkge1xuXG5cdFx0dGhyb3cgbmV3IEVycm9yKCBcImNhbGwgdG8gYWJzdHJhY3QgbWV0aG9kXCIgKTtcblx0XHQvLyBpbXBsZW1lbnRhdGlvbnMgc2hhbGwgcmV0dXJuIHRoaXMucmVzdWx0QnVmZmVyXG5cblx0fSxcblxuXHRpbnRlcnZhbENoYW5nZWRfOiBmdW5jdGlvbiggaTEsIHQwLCB0MSApIHtcblxuXHRcdC8vIGVtcHR5XG5cblx0fVxuXG59ICk7XG5cbi8vIVxcIERFQ0xBUkUgQUxJQVMgQUZURVIgYXNzaWduIHByb3RvdHlwZSAhXG5PYmplY3QuYXNzaWduKCBJbnRlcnBvbGFudC5wcm90b3R5cGUsIHtcblxuXHQvLyggMCwgdCwgdDAgKSwgcmV0dXJucyB0aGlzLnJlc3VsdEJ1ZmZlclxuXHRiZWZvcmVTdGFydF86IEludGVycG9sYW50LnByb3RvdHlwZS5jb3B5U2FtcGxlVmFsdWVfLFxuXG5cdC8vKCBOLTEsIHROLTEsIHQgKSwgcmV0dXJucyB0aGlzLnJlc3VsdEJ1ZmZlclxuXHRhZnRlckVuZF86IEludGVycG9sYW50LnByb3RvdHlwZS5jb3B5U2FtcGxlVmFsdWVfLFxuXG59ICk7XG5cbi8qKlxuICogRmFzdCBhbmQgc2ltcGxlIGN1YmljIHNwbGluZSBpbnRlcnBvbGFudC5cbiAqXG4gKiBJdCB3YXMgZGVyaXZlZCBmcm9tIGEgSGVybWl0aWFuIGNvbnN0cnVjdGlvbiBzZXR0aW5nIHRoZSBmaXJzdCBkZXJpdmF0aXZlXG4gKiBhdCBlYWNoIHNhbXBsZSBwb3NpdGlvbiB0byB0aGUgbGluZWFyIHNsb3BlIGJldHdlZW4gbmVpZ2hib3JpbmcgcG9zaXRpb25zXG4gKiBvdmVyIHRoZWlyIHBhcmFtZXRlciBpbnRlcnZhbC5cbiAqXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gQ3ViaWNJbnRlcnBvbGFudCggcGFyYW1ldGVyUG9zaXRpb25zLCBzYW1wbGVWYWx1ZXMsIHNhbXBsZVNpemUsIHJlc3VsdEJ1ZmZlciApIHtcblxuXHRJbnRlcnBvbGFudC5jYWxsKFxuXHRcdFx0dGhpcywgcGFyYW1ldGVyUG9zaXRpb25zLCBzYW1wbGVWYWx1ZXMsIHNhbXBsZVNpemUsIHJlc3VsdEJ1ZmZlciApO1xuXG5cdHRoaXMuX3dlaWdodFByZXYgPSAtMDtcblx0dGhpcy5fb2Zmc2V0UHJldiA9IC0wO1xuXHR0aGlzLl93ZWlnaHROZXh0ID0gLTA7XG5cdHRoaXMuX29mZnNldE5leHQgPSAtMDtcblxufVxuXG5DdWJpY0ludGVycG9sYW50LnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIEludGVycG9sYW50LnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IEN1YmljSW50ZXJwb2xhbnQsXG5cblx0RGVmYXVsdFNldHRpbmdzXzoge1xuXG5cdFx0ZW5kaW5nU3RhcnQ6IFx0WmVyb0N1cnZhdHVyZUVuZGluZyxcblx0XHRlbmRpbmdFbmQ6XHRcdFplcm9DdXJ2YXR1cmVFbmRpbmdcblxuXHR9LFxuXG5cdGludGVydmFsQ2hhbmdlZF86IGZ1bmN0aW9uKCBpMSwgdDAsIHQxICkge1xuXG5cdFx0dmFyIHBwID0gdGhpcy5wYXJhbWV0ZXJQb3NpdGlvbnMsXG5cdFx0XHRpUHJldiA9IGkxIC0gMixcblx0XHRcdGlOZXh0ID0gaTEgKyAxLFxuXG5cdFx0XHR0UHJldiA9IHBwWyBpUHJldiBdLFxuXHRcdFx0dE5leHQgPSBwcFsgaU5leHQgXTtcblxuXHRcdGlmICggdFByZXYgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0c3dpdGNoICggdGhpcy5nZXRTZXR0aW5nc18oKS5lbmRpbmdTdGFydCApIHtcblxuXHRcdFx0XHRjYXNlIFplcm9TbG9wZUVuZGluZzpcblxuXHRcdFx0XHRcdC8vIGYnKHQwKSA9IDBcblx0XHRcdFx0XHRpUHJldiA9IGkxO1xuXHRcdFx0XHRcdHRQcmV2ID0gMiAqIHQwIC0gdDE7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlIFdyYXBBcm91bmRFbmRpbmc6XG5cblx0XHRcdFx0XHQvLyB1c2UgdGhlIG90aGVyIGVuZCBvZiB0aGUgY3VydmVcblx0XHRcdFx0XHRpUHJldiA9IHBwLmxlbmd0aCAtIDI7XG5cdFx0XHRcdFx0dFByZXYgPSB0MCArIHBwWyBpUHJldiBdIC0gcHBbIGlQcmV2ICsgMSBdO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0ZGVmYXVsdDogLy8gWmVyb0N1cnZhdHVyZUVuZGluZ1xuXG5cdFx0XHRcdFx0Ly8gZicnKHQwKSA9IDAgYS5rLmEuIE5hdHVyYWwgU3BsaW5lXG5cdFx0XHRcdFx0aVByZXYgPSBpMTtcblx0XHRcdFx0XHR0UHJldiA9IHQxO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHROZXh0ID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHN3aXRjaCAoIHRoaXMuZ2V0U2V0dGluZ3NfKCkuZW5kaW5nRW5kICkge1xuXG5cdFx0XHRcdGNhc2UgWmVyb1Nsb3BlRW5kaW5nOlxuXG5cdFx0XHRcdFx0Ly8gZicodE4pID0gMFxuXHRcdFx0XHRcdGlOZXh0ID0gaTE7XG5cdFx0XHRcdFx0dE5leHQgPSAyICogdDEgLSB0MDtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgV3JhcEFyb3VuZEVuZGluZzpcblxuXHRcdFx0XHRcdC8vIHVzZSB0aGUgb3RoZXIgZW5kIG9mIHRoZSBjdXJ2ZVxuXHRcdFx0XHRcdGlOZXh0ID0gMTtcblx0XHRcdFx0XHR0TmV4dCA9IHQxICsgcHBbIDEgXSAtIHBwWyAwIF07XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRkZWZhdWx0OiAvLyBaZXJvQ3VydmF0dXJlRW5kaW5nXG5cblx0XHRcdFx0XHQvLyBmJycodE4pID0gMCwgYS5rLmEuIE5hdHVyYWwgU3BsaW5lXG5cdFx0XHRcdFx0aU5leHQgPSBpMSAtIDE7XG5cdFx0XHRcdFx0dE5leHQgPSB0MDtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIGhhbGZEdCA9ICggdDEgLSB0MCApICogMC41LFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemU7XG5cblx0XHR0aGlzLl93ZWlnaHRQcmV2ID0gaGFsZkR0IC8gKCB0MCAtIHRQcmV2ICk7XG5cdFx0dGhpcy5fd2VpZ2h0TmV4dCA9IGhhbGZEdCAvICggdE5leHQgLSB0MSApO1xuXHRcdHRoaXMuX29mZnNldFByZXYgPSBpUHJldiAqIHN0cmlkZTtcblx0XHR0aGlzLl9vZmZzZXROZXh0ID0gaU5leHQgKiBzdHJpZGU7XG5cblx0fSxcblxuXHRpbnRlcnBvbGF0ZV86IGZ1bmN0aW9uKCBpMSwgdDAsIHQsIHQxICkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IHRoaXMucmVzdWx0QnVmZmVyLFxuXHRcdFx0dmFsdWVzID0gdGhpcy5zYW1wbGVWYWx1ZXMsXG5cdFx0XHRzdHJpZGUgPSB0aGlzLnZhbHVlU2l6ZSxcblxuXHRcdFx0bzEgPSBpMSAqIHN0cmlkZSxcdFx0bzAgPSBvMSAtIHN0cmlkZSxcblx0XHRcdG9QID0gdGhpcy5fb2Zmc2V0UHJldiwgXHRvTiA9IHRoaXMuX29mZnNldE5leHQsXG5cdFx0XHR3UCA9IHRoaXMuX3dlaWdodFByZXYsXHR3TiA9IHRoaXMuX3dlaWdodE5leHQsXG5cblx0XHRcdHAgPSAoIHQgLSB0MCApIC8gKCB0MSAtIHQwICksXG5cdFx0XHRwcCA9IHAgKiBwLFxuXHRcdFx0cHBwID0gcHAgKiBwO1xuXG5cdFx0Ly8gZXZhbHVhdGUgcG9seW5vbWlhbHNcblxuXHRcdHZhciBzUCA9ICAgICAtIHdQICAgKiBwcHAgICArICAgICAgICAgMiAqIHdQICAgICogcHAgICAgLSAgICAgICAgICB3UCAgICogcDtcblx0XHR2YXIgczAgPSAoIDEgKyB3UCApICogcHBwICAgKyAoLTEuNSAtIDIgKiB3UCApICAqIHBwICAgICsgKCAtMC41ICsgd1AgKSAqIHAgICAgICsgMTtcblx0XHR2YXIgczEgPSAoLTEgLSB3TiApICogcHBwICAgKyAoIDEuNSArICAgd04gICApICAqIHBwICAgICsgICAgMC41ICAgICAgICAqIHA7XG5cdFx0dmFyIHNOID0gICAgICAgd04gICAqIHBwcCAgIC0gICAgICAgICAgIHdOICAgICAgKiBwcDtcblxuXHRcdC8vIGNvbWJpbmUgZGF0YSBsaW5lYXJseVxuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBzdHJpZGU7ICsrIGkgKSB7XG5cblx0XHRcdHJlc3VsdFsgaSBdID1cblx0XHRcdFx0XHRzUCAqIHZhbHVlc1sgb1AgKyBpIF0gK1xuXHRcdFx0XHRcdHMwICogdmFsdWVzWyBvMCArIGkgXSArXG5cdFx0XHRcdFx0czEgKiB2YWx1ZXNbIG8xICsgaSBdICtcblx0XHRcdFx0XHRzTiAqIHZhbHVlc1sgb04gKyBpIF07XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBMaW5lYXJJbnRlcnBvbGFudCggcGFyYW1ldGVyUG9zaXRpb25zLCBzYW1wbGVWYWx1ZXMsIHNhbXBsZVNpemUsIHJlc3VsdEJ1ZmZlciApIHtcblxuXHRJbnRlcnBvbGFudC5jYWxsKCB0aGlzLCBwYXJhbWV0ZXJQb3NpdGlvbnMsIHNhbXBsZVZhbHVlcywgc2FtcGxlU2l6ZSwgcmVzdWx0QnVmZmVyICk7XG5cbn1cblxuTGluZWFySW50ZXJwb2xhbnQucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggSW50ZXJwb2xhbnQucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTGluZWFySW50ZXJwb2xhbnQsXG5cblx0aW50ZXJwb2xhdGVfOiBmdW5jdGlvbiggaTEsIHQwLCB0LCB0MSApIHtcblxuXHRcdHZhciByZXN1bHQgPSB0aGlzLnJlc3VsdEJ1ZmZlcixcblx0XHRcdHZhbHVlcyA9IHRoaXMuc2FtcGxlVmFsdWVzLFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cblx0XHRcdG9mZnNldDEgPSBpMSAqIHN0cmlkZSxcblx0XHRcdG9mZnNldDAgPSBvZmZzZXQxIC0gc3RyaWRlLFxuXG5cdFx0XHR3ZWlnaHQxID0gKCB0IC0gdDAgKSAvICggdDEgLSB0MCApLFxuXHRcdFx0d2VpZ2h0MCA9IDEgLSB3ZWlnaHQxO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBzdHJpZGU7ICsrIGkgKSB7XG5cblx0XHRcdHJlc3VsdFsgaSBdID1cblx0XHRcdFx0XHR2YWx1ZXNbIG9mZnNldDAgKyBpIF0gKiB3ZWlnaHQwICtcblx0XHRcdFx0XHR2YWx1ZXNbIG9mZnNldDEgKyBpIF0gKiB3ZWlnaHQxO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKlxuICogSW50ZXJwb2xhbnQgdGhhdCBldmFsdWF0ZXMgdG8gdGhlIHNhbXBsZSB2YWx1ZSBhdCB0aGUgcG9zaXRpb24gcHJlY2VlZGluZ1xuICogdGhlIHBhcmFtZXRlci5cbiAqXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gRGlzY3JldGVJbnRlcnBvbGFudCggcGFyYW1ldGVyUG9zaXRpb25zLCBzYW1wbGVWYWx1ZXMsIHNhbXBsZVNpemUsIHJlc3VsdEJ1ZmZlciApIHtcblxuXHRJbnRlcnBvbGFudC5jYWxsKCB0aGlzLCBwYXJhbWV0ZXJQb3NpdGlvbnMsIHNhbXBsZVZhbHVlcywgc2FtcGxlU2l6ZSwgcmVzdWx0QnVmZmVyICk7XG5cbn1cblxuRGlzY3JldGVJbnRlcnBvbGFudC5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBJbnRlcnBvbGFudC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBEaXNjcmV0ZUludGVycG9sYW50LFxuXG5cdGludGVycG9sYXRlXzogZnVuY3Rpb24oIGkxLCB0MCwgdCwgdDEgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5jb3B5U2FtcGxlVmFsdWVfKCBpMSAtIDEgKTtcblxuXHR9XG5cbn0gKTtcblxudmFyIEtleWZyYW1lVHJhY2tQcm90b3R5cGU7XG5cbktleWZyYW1lVHJhY2tQcm90b3R5cGUgPSB7XG5cblx0VGltZUJ1ZmZlclR5cGU6IEZsb2F0MzJBcnJheSxcblx0VmFsdWVCdWZmZXJUeXBlOiBGbG9hdDMyQXJyYXksXG5cblx0RGVmYXVsdEludGVycG9sYXRpb246IEludGVycG9sYXRlTGluZWFyLFxuXG5cdEludGVycG9sYW50RmFjdG9yeU1ldGhvZERpc2NyZXRlOiBmdW5jdGlvbiAoIHJlc3VsdCApIHtcblxuXHRcdHJldHVybiBuZXcgRGlzY3JldGVJbnRlcnBvbGFudChcblx0XHRcdFx0dGhpcy50aW1lcywgdGhpcy52YWx1ZXMsIHRoaXMuZ2V0VmFsdWVTaXplKCksIHJlc3VsdCApO1xuXG5cdH0sXG5cblx0SW50ZXJwb2xhbnRGYWN0b3J5TWV0aG9kTGluZWFyOiBmdW5jdGlvbiAoIHJlc3VsdCApIHtcblxuXHRcdHJldHVybiBuZXcgTGluZWFySW50ZXJwb2xhbnQoXG5cdFx0XHRcdHRoaXMudGltZXMsIHRoaXMudmFsdWVzLCB0aGlzLmdldFZhbHVlU2l6ZSgpLCByZXN1bHQgKTtcblxuXHR9LFxuXG5cdEludGVycG9sYW50RmFjdG9yeU1ldGhvZFNtb290aDogZnVuY3Rpb24gKCByZXN1bHQgKSB7XG5cblx0XHRyZXR1cm4gbmV3IEN1YmljSW50ZXJwb2xhbnQoXG5cdFx0XHRcdHRoaXMudGltZXMsIHRoaXMudmFsdWVzLCB0aGlzLmdldFZhbHVlU2l6ZSgpLCByZXN1bHQgKTtcblxuXHR9LFxuXG5cdHNldEludGVycG9sYXRpb246IGZ1bmN0aW9uICggaW50ZXJwb2xhdGlvbiApIHtcblxuXHRcdHZhciBmYWN0b3J5TWV0aG9kO1xuXG5cdFx0c3dpdGNoICggaW50ZXJwb2xhdGlvbiApIHtcblxuXHRcdFx0Y2FzZSBJbnRlcnBvbGF0ZURpc2NyZXRlOlxuXG5cdFx0XHRcdGZhY3RvcnlNZXRob2QgPSB0aGlzLkludGVycG9sYW50RmFjdG9yeU1ldGhvZERpc2NyZXRlO1xuXG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIEludGVycG9sYXRlTGluZWFyOlxuXG5cdFx0XHRcdGZhY3RvcnlNZXRob2QgPSB0aGlzLkludGVycG9sYW50RmFjdG9yeU1ldGhvZExpbmVhcjtcblxuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBJbnRlcnBvbGF0ZVNtb290aDpcblxuXHRcdFx0XHRmYWN0b3J5TWV0aG9kID0gdGhpcy5JbnRlcnBvbGFudEZhY3RvcnlNZXRob2RTbW9vdGg7XG5cblx0XHRcdFx0YnJlYWs7XG5cblx0XHR9XG5cblx0XHRpZiAoIGZhY3RvcnlNZXRob2QgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dmFyIG1lc3NhZ2UgPSBcInVuc3VwcG9ydGVkIGludGVycG9sYXRpb24gZm9yIFwiICtcblx0XHRcdFx0XHR0aGlzLlZhbHVlVHlwZU5hbWUgKyBcIiBrZXlmcmFtZSB0cmFjayBuYW1lZCBcIiArIHRoaXMubmFtZTtcblxuXHRcdFx0aWYgKCB0aGlzLmNyZWF0ZUludGVycG9sYW50ID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gZmFsbCBiYWNrIHRvIGRlZmF1bHQsIHVubGVzcyB0aGUgZGVmYXVsdCBpdHNlbGYgaXMgbWVzc2VkIHVwXG5cdFx0XHRcdGlmICggaW50ZXJwb2xhdGlvbiAhPT0gdGhpcy5EZWZhdWx0SW50ZXJwb2xhdGlvbiApIHtcblxuXHRcdFx0XHRcdHRoaXMuc2V0SW50ZXJwb2xhdGlvbiggdGhpcy5EZWZhdWx0SW50ZXJwb2xhdGlvbiApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIG1lc3NhZ2UgKTsgLy8gZmF0YWwsIGluIHRoaXMgY2FzZVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRjb25zb2xlLndhcm4oIG1lc3NhZ2UgKTtcblx0XHRcdHJldHVybjtcblxuXHRcdH1cblxuXHRcdHRoaXMuY3JlYXRlSW50ZXJwb2xhbnQgPSBmYWN0b3J5TWV0aG9kO1xuXG5cdH0sXG5cblx0Z2V0SW50ZXJwb2xhdGlvbjogZnVuY3Rpb24gKCkge1xuXG5cdFx0c3dpdGNoICggdGhpcy5jcmVhdGVJbnRlcnBvbGFudCApIHtcblxuXHRcdFx0Y2FzZSB0aGlzLkludGVycG9sYW50RmFjdG9yeU1ldGhvZERpc2NyZXRlOlxuXG5cdFx0XHRcdHJldHVybiBJbnRlcnBvbGF0ZURpc2NyZXRlO1xuXG5cdFx0XHRjYXNlIHRoaXMuSW50ZXJwb2xhbnRGYWN0b3J5TWV0aG9kTGluZWFyOlxuXG5cdFx0XHRcdHJldHVybiBJbnRlcnBvbGF0ZUxpbmVhcjtcblxuXHRcdFx0Y2FzZSB0aGlzLkludGVycG9sYW50RmFjdG9yeU1ldGhvZFNtb290aDpcblxuXHRcdFx0XHRyZXR1cm4gSW50ZXJwb2xhdGVTbW9vdGg7XG5cblx0XHR9XG5cblx0fSxcblxuXHRnZXRWYWx1ZVNpemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnZhbHVlcy5sZW5ndGggLyB0aGlzLnRpbWVzLmxlbmd0aDtcblxuXHR9LFxuXG5cdC8vIG1vdmUgYWxsIGtleWZyYW1lcyBlaXRoZXIgZm9yd2FyZHMgb3IgYmFja3dhcmRzIGluIHRpbWVcblx0c2hpZnQ6IGZ1bmN0aW9uICggdGltZU9mZnNldCApIHtcblxuXHRcdGlmICggdGltZU9mZnNldCAhPT0gMC4wICkge1xuXG5cdFx0XHR2YXIgdGltZXMgPSB0aGlzLnRpbWVzO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSB0aW1lcy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdFx0dGltZXNbIGkgXSArPSB0aW1lT2Zmc2V0O1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdC8vIHNjYWxlIGFsbCBrZXlmcmFtZSB0aW1lcyBieSBhIGZhY3RvciAodXNlZnVsIGZvciBmcmFtZSA8LT4gc2Vjb25kcyBjb252ZXJzaW9ucylcblx0c2NhbGU6IGZ1bmN0aW9uICggdGltZVNjYWxlICkge1xuXG5cdFx0aWYgKCB0aW1lU2NhbGUgIT09IDEuMCApIHtcblxuXHRcdFx0dmFyIHRpbWVzID0gdGhpcy50aW1lcztcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBuID0gdGltZXMubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHRcdHRpbWVzWyBpIF0gKj0gdGltZVNjYWxlO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdC8vIHJlbW92ZXMga2V5ZnJhbWVzIGJlZm9yZSBhbmQgYWZ0ZXIgYW5pbWF0aW9uIHdpdGhvdXQgY2hhbmdpbmcgYW55IHZhbHVlcyB3aXRoaW4gdGhlIHJhbmdlIFtzdGFydFRpbWUsIGVuZFRpbWVdLlxuXHQvLyBJTVBPUlRBTlQ6IFdlIGRvIG5vdCBzaGlmdCBhcm91bmQga2V5cyB0byB0aGUgc3RhcnQgb2YgdGhlIHRyYWNrIHRpbWUsIGJlY2F1c2UgZm9yIGludGVycG9sYXRlZCBrZXlzIHRoaXMgd2lsbCBjaGFuZ2UgdGhlaXIgdmFsdWVzXG5cdHRyaW06IGZ1bmN0aW9uICggc3RhcnRUaW1lLCBlbmRUaW1lICkge1xuXG5cdFx0dmFyIHRpbWVzID0gdGhpcy50aW1lcyxcblx0XHRcdG5LZXlzID0gdGltZXMubGVuZ3RoLFxuXHRcdFx0ZnJvbSA9IDAsXG5cdFx0XHR0byA9IG5LZXlzIC0gMTtcblxuXHRcdHdoaWxlICggZnJvbSAhPT0gbktleXMgJiYgdGltZXNbIGZyb20gXSA8IHN0YXJ0VGltZSApICsrIGZyb207XG5cdFx0d2hpbGUgKCB0byAhPT0gLSAxICYmIHRpbWVzWyB0byBdID4gZW5kVGltZSApIC0tIHRvO1xuXG5cdFx0KysgdG87IC8vIGluY2x1c2l2ZSAtPiBleGNsdXNpdmUgYm91bmRcblxuXHRcdGlmICggZnJvbSAhPT0gMCB8fCB0byAhPT0gbktleXMgKSB7XG5cblx0XHRcdC8vIGVtcHR5IHRyYWNrcyBhcmUgZm9yYmlkZGVuLCBzbyBrZWVwIGF0IGxlYXN0IG9uZSBrZXlmcmFtZVxuXHRcdFx0aWYgKCBmcm9tID49IHRvICkgdG8gPSBNYXRoLm1heCggdG8sIDEgKSwgZnJvbSA9IHRvIC0gMTtcblxuXHRcdFx0dmFyIHN0cmlkZSA9IHRoaXMuZ2V0VmFsdWVTaXplKCk7XG5cdFx0XHR0aGlzLnRpbWVzID0gQW5pbWF0aW9uVXRpbHMuYXJyYXlTbGljZSggdGltZXMsIGZyb20sIHRvICk7XG5cdFx0XHR0aGlzLnZhbHVlcyA9IEFuaW1hdGlvblV0aWxzLlxuXHRcdFx0XHRcdGFycmF5U2xpY2UoIHRoaXMudmFsdWVzLCBmcm9tICogc3RyaWRlLCB0byAqIHN0cmlkZSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHQvLyBlbnN1cmUgd2UgZG8gbm90IGdldCBhIEdhcmJhZ2VJbkdhcmJhZ2VPdXQgc2l0dWF0aW9uLCBtYWtlIHN1cmUgdHJhY2tzIGFyZSBhdCBsZWFzdCBtaW5pbWFsbHkgdmlhYmxlXG5cdHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdmFsaWQgPSB0cnVlO1xuXG5cdFx0dmFyIHZhbHVlU2l6ZSA9IHRoaXMuZ2V0VmFsdWVTaXplKCk7XG5cdFx0aWYgKCB2YWx1ZVNpemUgLSBNYXRoLmZsb29yKCB2YWx1ZVNpemUgKSAhPT0gMCApIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggXCJpbnZhbGlkIHZhbHVlIHNpemUgaW4gdHJhY2tcIiwgdGhpcyApO1xuXHRcdFx0dmFsaWQgPSBmYWxzZTtcblxuXHRcdH1cblxuXHRcdHZhciB0aW1lcyA9IHRoaXMudGltZXMsXG5cdFx0XHR2YWx1ZXMgPSB0aGlzLnZhbHVlcyxcblxuXHRcdFx0bktleXMgPSB0aW1lcy5sZW5ndGg7XG5cblx0XHRpZiAoIG5LZXlzID09PSAwICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCBcInRyYWNrIGlzIGVtcHR5XCIsIHRoaXMgKTtcblx0XHRcdHZhbGlkID0gZmFsc2U7XG5cblx0XHR9XG5cblx0XHR2YXIgcHJldlRpbWUgPSBudWxsO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuS2V5czsgaSArKyApIHtcblxuXHRcdFx0dmFyIGN1cnJUaW1lID0gdGltZXNbIGkgXTtcblxuXHRcdFx0aWYgKCB0eXBlb2YgY3VyclRpbWUgPT09ICdudW1iZXInICYmIGlzTmFOKCBjdXJyVGltZSApICkge1xuXG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoIFwidGltZSBpcyBub3QgYSB2YWxpZCBudW1iZXJcIiwgdGhpcywgaSwgY3VyclRpbWUgKTtcblx0XHRcdFx0dmFsaWQgPSBmYWxzZTtcblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBwcmV2VGltZSAhPT0gbnVsbCAmJiBwcmV2VGltZSA+IGN1cnJUaW1lICkge1xuXG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoIFwib3V0IG9mIG9yZGVyIGtleXNcIiwgdGhpcywgaSwgY3VyclRpbWUsIHByZXZUaW1lICk7XG5cdFx0XHRcdHZhbGlkID0gZmFsc2U7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHR9XG5cblx0XHRcdHByZXZUaW1lID0gY3VyclRpbWU7XG5cblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRpZiAoIEFuaW1hdGlvblV0aWxzLmlzVHlwZWRBcnJheSggdmFsdWVzICkgKSB7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBuID0gdmFsdWVzLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdFx0XHRcdHZhciB2YWx1ZSA9IHZhbHVlc1sgaSBdO1xuXG5cdFx0XHRcdFx0aWYgKCBpc05hTiggdmFsdWUgKSApIHtcblxuXHRcdFx0XHRcdFx0Y29uc29sZS5lcnJvciggXCJ2YWx1ZSBpcyBub3QgYSB2YWxpZCBudW1iZXJcIiwgdGhpcywgaSwgdmFsdWUgKTtcblx0XHRcdFx0XHRcdHZhbGlkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiB2YWxpZDtcblxuXHR9LFxuXG5cdC8vIHJlbW92ZXMgZXF1aXZhbGVudCBzZXF1ZW50aWFsIGtleXMgYXMgY29tbW9uIGluIG1vcnBoIHRhcmdldCBzZXF1ZW5jZXNcblx0Ly8gKDAsMCwwLDAsMSwxLDEsMCwwLDAsMCwwLDAsMCkgLS0+ICgwLDAsMSwxLDAsMClcblx0b3B0aW1pemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciB0aW1lcyA9IHRoaXMudGltZXMsXG5cdFx0XHR2YWx1ZXMgPSB0aGlzLnZhbHVlcyxcblx0XHRcdHN0cmlkZSA9IHRoaXMuZ2V0VmFsdWVTaXplKCksXG5cblx0XHRcdHNtb290aEludGVycG9sYXRpb24gPSB0aGlzLmdldEludGVycG9sYXRpb24oKSA9PT0gSW50ZXJwb2xhdGVTbW9vdGgsXG5cblx0XHRcdHdyaXRlSW5kZXggPSAxLFxuXHRcdFx0bGFzdEluZGV4ID0gdGltZXMubGVuZ3RoIC0gMTtcblxuXHRcdGZvciAoIHZhciBpID0gMTsgaSA8IGxhc3RJbmRleDsgKysgaSApIHtcblxuXHRcdFx0dmFyIGtlZXAgPSBmYWxzZTtcblxuXHRcdFx0dmFyIHRpbWUgPSB0aW1lc1sgaSBdO1xuXHRcdFx0dmFyIHRpbWVOZXh0ID0gdGltZXNbIGkgKyAxIF07XG5cblx0XHRcdC8vIHJlbW92ZSBhZGphY2VudCBrZXlmcmFtZXMgc2NoZWR1bGVkIGF0IHRoZSBzYW1lIHRpbWVcblxuXHRcdFx0aWYgKCB0aW1lICE9PSB0aW1lTmV4dCAmJiAoIGkgIT09IDEgfHwgdGltZSAhPT0gdGltZVsgMCBdICkgKSB7XG5cblx0XHRcdFx0aWYgKCAhIHNtb290aEludGVycG9sYXRpb24gKSB7XG5cblx0XHRcdFx0XHQvLyByZW1vdmUgdW5uZWNlc3Nhcnkga2V5ZnJhbWVzIHNhbWUgYXMgdGhlaXIgbmVpZ2hib3JzXG5cblx0XHRcdFx0XHR2YXIgb2Zmc2V0ID0gaSAqIHN0cmlkZSxcblx0XHRcdFx0XHRcdG9mZnNldFAgPSBvZmZzZXQgLSBzdHJpZGUsXG5cdFx0XHRcdFx0XHRvZmZzZXROID0gb2Zmc2V0ICsgc3RyaWRlO1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqICE9PSBzdHJpZGU7ICsrIGogKSB7XG5cblx0XHRcdFx0XHRcdHZhciB2YWx1ZSA9IHZhbHVlc1sgb2Zmc2V0ICsgaiBdO1xuXG5cdFx0XHRcdFx0XHRpZiAoIHZhbHVlICE9PSB2YWx1ZXNbIG9mZnNldFAgKyBqIF0gfHxcblx0XHRcdFx0XHRcdFx0XHR2YWx1ZSAhPT0gdmFsdWVzWyBvZmZzZXROICsgaiBdICkge1xuXG5cdFx0XHRcdFx0XHRcdGtlZXAgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSBrZWVwID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBpbi1wbGFjZSBjb21wYWN0aW9uXG5cblx0XHRcdGlmICgga2VlcCApIHtcblxuXHRcdFx0XHRpZiAoIGkgIT09IHdyaXRlSW5kZXggKSB7XG5cblx0XHRcdFx0XHR0aW1lc1sgd3JpdGVJbmRleCBdID0gdGltZXNbIGkgXTtcblxuXHRcdFx0XHRcdHZhciByZWFkT2Zmc2V0ID0gaSAqIHN0cmlkZSxcblx0XHRcdFx0XHRcdHdyaXRlT2Zmc2V0ID0gd3JpdGVJbmRleCAqIHN0cmlkZTtcblxuXHRcdFx0XHRcdGZvciAoIHZhciBqID0gMDsgaiAhPT0gc3RyaWRlOyArKyBqIClcblxuXHRcdFx0XHRcdFx0dmFsdWVzWyB3cml0ZU9mZnNldCArIGogXSA9IHZhbHVlc1sgcmVhZE9mZnNldCArIGogXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Kysgd3JpdGVJbmRleDtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gZmx1c2ggbGFzdCBrZXlmcmFtZSAoY29tcGFjdGlvbiBsb29rcyBhaGVhZClcblxuXHRcdGlmICggbGFzdEluZGV4ID4gMCApIHtcblxuXHRcdFx0dGltZXNbIHdyaXRlSW5kZXggXSA9IHRpbWVzWyBsYXN0SW5kZXggXTtcblxuXHRcdFx0Zm9yICggdmFyIHJlYWRPZmZzZXQgPSBsYXN0SW5kZXggKiBzdHJpZGUsIHdyaXRlT2Zmc2V0ID0gd3JpdGVJbmRleCAqIHN0cmlkZSwgaiA9IDA7IGogIT09IHN0cmlkZTsgKysgaiApXG5cblx0XHRcdFx0dmFsdWVzWyB3cml0ZU9mZnNldCArIGogXSA9IHZhbHVlc1sgcmVhZE9mZnNldCArIGogXTtcblxuXHRcdFx0Kysgd3JpdGVJbmRleDtcblxuXHRcdH1cblxuXHRcdGlmICggd3JpdGVJbmRleCAhPT0gdGltZXMubGVuZ3RoICkge1xuXG5cdFx0XHR0aGlzLnRpbWVzID0gQW5pbWF0aW9uVXRpbHMuYXJyYXlTbGljZSggdGltZXMsIDAsIHdyaXRlSW5kZXggKTtcblx0XHRcdHRoaXMudmFsdWVzID0gQW5pbWF0aW9uVXRpbHMuYXJyYXlTbGljZSggdmFsdWVzLCAwLCB3cml0ZUluZGV4ICogc3RyaWRlICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9XG5cbn07XG5cbmZ1bmN0aW9uIEtleWZyYW1lVHJhY2tDb25zdHJ1Y3RvciggbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApIHtcblxuXHRpZiAoIG5hbWUgPT09IHVuZGVmaW5lZCApIHRocm93IG5ldyBFcnJvciggXCJ0cmFjayBuYW1lIGlzIHVuZGVmaW5lZFwiICk7XG5cblx0aWYgKCB0aW1lcyA9PT0gdW5kZWZpbmVkIHx8IHRpbWVzLmxlbmd0aCA9PT0gMCApIHtcblxuXHRcdHRocm93IG5ldyBFcnJvciggXCJubyBrZXlmcmFtZXMgaW4gdHJhY2sgbmFtZWQgXCIgKyBuYW1lICk7XG5cblx0fVxuXG5cdHRoaXMubmFtZSA9IG5hbWU7XG5cblx0dGhpcy50aW1lcyA9IEFuaW1hdGlvblV0aWxzLmNvbnZlcnRBcnJheSggdGltZXMsIHRoaXMuVGltZUJ1ZmZlclR5cGUgKTtcblx0dGhpcy52YWx1ZXMgPSBBbmltYXRpb25VdGlscy5jb252ZXJ0QXJyYXkoIHZhbHVlcywgdGhpcy5WYWx1ZUJ1ZmZlclR5cGUgKTtcblxuXHR0aGlzLnNldEludGVycG9sYXRpb24oIGludGVycG9sYXRpb24gfHwgdGhpcy5EZWZhdWx0SW50ZXJwb2xhdGlvbiApO1xuXG5cdHRoaXMudmFsaWRhdGUoKTtcblx0dGhpcy5vcHRpbWl6ZSgpO1xuXG59XG5cbi8qKlxuICpcbiAqIEEgVHJhY2sgb2YgdmVjdG9yZWQga2V5ZnJhbWUgdmFsdWVzLlxuICpcbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gVmVjdG9yS2V5ZnJhbWVUcmFjayggbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApIHtcblxuXHRLZXlmcmFtZVRyYWNrQ29uc3RydWN0b3IuY2FsbCggdGhpcywgbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApO1xuXG59XG5cblZlY3RvcktleWZyYW1lVHJhY2sucHJvdG90eXBlID1cblx0XHRPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBLZXlmcmFtZVRyYWNrUHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogVmVjdG9yS2V5ZnJhbWVUcmFjayxcblxuXHRWYWx1ZVR5cGVOYW1lOiAndmVjdG9yJ1xuXG5cdC8vIFZhbHVlQnVmZmVyVHlwZSBpcyBpbmhlcml0ZWRcblxuXHQvLyBEZWZhdWx0SW50ZXJwb2xhdGlvbiBpcyBpbmhlcml0ZWRcblxufSApO1xuXG4vKipcbiAqIFNwaGVyaWNhbCBsaW5lYXIgdW5pdCBxdWF0ZXJuaW9uIGludGVycG9sYW50LlxuICpcbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBRdWF0ZXJuaW9uTGluZWFySW50ZXJwb2xhbnQoIHBhcmFtZXRlclBvc2l0aW9ucywgc2FtcGxlVmFsdWVzLCBzYW1wbGVTaXplLCByZXN1bHRCdWZmZXIgKSB7XG5cblx0SW50ZXJwb2xhbnQuY2FsbCggdGhpcywgcGFyYW1ldGVyUG9zaXRpb25zLCBzYW1wbGVWYWx1ZXMsIHNhbXBsZVNpemUsIHJlc3VsdEJ1ZmZlciApO1xuXG59XG5cblF1YXRlcm5pb25MaW5lYXJJbnRlcnBvbGFudC5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBJbnRlcnBvbGFudC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBRdWF0ZXJuaW9uTGluZWFySW50ZXJwb2xhbnQsXG5cblx0aW50ZXJwb2xhdGVfOiBmdW5jdGlvbiggaTEsIHQwLCB0LCB0MSApIHtcblxuXHRcdHZhciByZXN1bHQgPSB0aGlzLnJlc3VsdEJ1ZmZlcixcblx0XHRcdHZhbHVlcyA9IHRoaXMuc2FtcGxlVmFsdWVzLFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cblx0XHRcdG9mZnNldCA9IGkxICogc3RyaWRlLFxuXG5cdFx0XHRhbHBoYSA9ICggdCAtIHQwICkgLyAoIHQxIC0gdDAgKTtcblxuXHRcdGZvciAoIHZhciBlbmQgPSBvZmZzZXQgKyBzdHJpZGU7IG9mZnNldCAhPT0gZW5kOyBvZmZzZXQgKz0gNCApIHtcblxuXHRcdFx0UXVhdGVybmlvbi5zbGVycEZsYXQoIHJlc3VsdCwgMCxcblx0XHRcdFx0XHR2YWx1ZXMsIG9mZnNldCAtIHN0cmlkZSwgdmFsdWVzLCBvZmZzZXQsIGFscGhhICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqXG4gKiBBIFRyYWNrIG9mIHF1YXRlcm5pb24ga2V5ZnJhbWUgdmFsdWVzLlxuICpcbiAqIEBhdXRob3IgQmVuIEhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW8vXG4gKiBAYXV0aG9yIERhdmlkIFNhcm5vIC8gaHR0cDovL2xpZ2h0aGF1cy51cy9cbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBRdWF0ZXJuaW9uS2V5ZnJhbWVUcmFjayggbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApIHtcblxuXHRLZXlmcmFtZVRyYWNrQ29uc3RydWN0b3IuY2FsbCggdGhpcywgbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApO1xuXG59XG5cblF1YXRlcm5pb25LZXlmcmFtZVRyYWNrLnByb3RvdHlwZSA9XG5cdFx0T2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggS2V5ZnJhbWVUcmFja1Byb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IFF1YXRlcm5pb25LZXlmcmFtZVRyYWNrLFxuXG5cdFZhbHVlVHlwZU5hbWU6ICdxdWF0ZXJuaW9uJyxcblxuXHQvLyBWYWx1ZUJ1ZmZlclR5cGUgaXMgaW5oZXJpdGVkXG5cblx0RGVmYXVsdEludGVycG9sYXRpb246IEludGVycG9sYXRlTGluZWFyLFxuXG5cdEludGVycG9sYW50RmFjdG9yeU1ldGhvZExpbmVhcjogZnVuY3Rpb24oIHJlc3VsdCApIHtcblxuXHRcdHJldHVybiBuZXcgUXVhdGVybmlvbkxpbmVhckludGVycG9sYW50KFxuXHRcdFx0XHR0aGlzLnRpbWVzLCB0aGlzLnZhbHVlcywgdGhpcy5nZXRWYWx1ZVNpemUoKSwgcmVzdWx0ICk7XG5cblx0fSxcblxuXHRJbnRlcnBvbGFudEZhY3RvcnlNZXRob2RTbW9vdGg6IHVuZGVmaW5lZCAvLyBub3QgeWV0IGltcGxlbWVudGVkXG5cbn0gKTtcblxuLyoqXG4gKlxuICogQSBUcmFjayBvZiBudW1lcmljIGtleWZyYW1lIHZhbHVlcy5cbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gTnVtYmVyS2V5ZnJhbWVUcmFjayggbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApIHtcblxuXHRLZXlmcmFtZVRyYWNrQ29uc3RydWN0b3IuY2FsbCggdGhpcywgbmFtZSwgdGltZXMsIHZhbHVlcywgaW50ZXJwb2xhdGlvbiApO1xuXG59XG5cbk51bWJlcktleWZyYW1lVHJhY2sucHJvdG90eXBlID1cblx0XHRPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBLZXlmcmFtZVRyYWNrUHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogTnVtYmVyS2V5ZnJhbWVUcmFjayxcblxuXHRWYWx1ZVR5cGVOYW1lOiAnbnVtYmVyJ1xuXG5cdC8vIFZhbHVlQnVmZmVyVHlwZSBpcyBpbmhlcml0ZWRcblxuXHQvLyBEZWZhdWx0SW50ZXJwb2xhdGlvbiBpcyBpbmhlcml0ZWRcblxufSApO1xuXG4vKipcbiAqXG4gKiBBIFRyYWNrIHRoYXQgaW50ZXJwb2xhdGVzIFN0cmluZ3NcbiAqXG4gKlxuICogQGF1dGhvciBCZW4gSG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pby9cbiAqIEBhdXRob3IgRGF2aWQgU2Fybm8gLyBodHRwOi8vbGlnaHRoYXVzLnVzL1xuICogQGF1dGhvciB0c2Nod1xuICovXG5cbmZ1bmN0aW9uIFN0cmluZ0tleWZyYW1lVHJhY2soIG5hbWUsIHRpbWVzLCB2YWx1ZXMsIGludGVycG9sYXRpb24gKSB7XG5cblx0S2V5ZnJhbWVUcmFja0NvbnN0cnVjdG9yLmNhbGwoIHRoaXMsIG5hbWUsIHRpbWVzLCB2YWx1ZXMsIGludGVycG9sYXRpb24gKTtcblxufVxuXG5TdHJpbmdLZXlmcmFtZVRyYWNrLnByb3RvdHlwZSA9XG5cdFx0T2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggS2V5ZnJhbWVUcmFja1Byb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IFN0cmluZ0tleWZyYW1lVHJhY2ssXG5cblx0VmFsdWVUeXBlTmFtZTogJ3N0cmluZycsXG5cdFZhbHVlQnVmZmVyVHlwZTogQXJyYXksXG5cblx0RGVmYXVsdEludGVycG9sYXRpb246IEludGVycG9sYXRlRGlzY3JldGUsXG5cblx0SW50ZXJwb2xhbnRGYWN0b3J5TWV0aG9kTGluZWFyOiB1bmRlZmluZWQsXG5cblx0SW50ZXJwb2xhbnRGYWN0b3J5TWV0aG9kU21vb3RoOiB1bmRlZmluZWRcblxufSApO1xuXG4vKipcbiAqXG4gKiBBIFRyYWNrIG9mIEJvb2xlYW4ga2V5ZnJhbWUgdmFsdWVzLlxuICpcbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gQm9vbGVhbktleWZyYW1lVHJhY2soIG5hbWUsIHRpbWVzLCB2YWx1ZXMgKSB7XG5cblx0S2V5ZnJhbWVUcmFja0NvbnN0cnVjdG9yLmNhbGwoIHRoaXMsIG5hbWUsIHRpbWVzLCB2YWx1ZXMgKTtcblxufVxuXG5Cb29sZWFuS2V5ZnJhbWVUcmFjay5wcm90b3R5cGUgPVxuXHRcdE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIEtleWZyYW1lVHJhY2tQcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBCb29sZWFuS2V5ZnJhbWVUcmFjayxcblxuXHRWYWx1ZVR5cGVOYW1lOiAnYm9vbCcsXG5cdFZhbHVlQnVmZmVyVHlwZTogQXJyYXksXG5cblx0RGVmYXVsdEludGVycG9sYXRpb246IEludGVycG9sYXRlRGlzY3JldGUsXG5cblx0SW50ZXJwb2xhbnRGYWN0b3J5TWV0aG9kTGluZWFyOiB1bmRlZmluZWQsXG5cdEludGVycG9sYW50RmFjdG9yeU1ldGhvZFNtb290aDogdW5kZWZpbmVkXG5cblx0Ly8gTm90ZTogQWN0dWFsbHkgdGhpcyB0cmFjayBjb3VsZCBoYXZlIGEgb3B0aW1pemVkIC8gY29tcHJlc3NlZFxuXHQvLyByZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSB2YWx1ZSBhbmQgYSBjdXN0b20gaW50ZXJwb2xhbnQgdGhhdFxuXHQvLyBjb21wdXRlcyBcImZpcnN0VmFsdWUgXiBpc09kZCggaW5kZXggKVwiLlxuXG59ICk7XG5cbi8qKlxuICpcbiAqIEEgVHJhY2sgb2Yga2V5ZnJhbWUgdmFsdWVzIHRoYXQgcmVwcmVzZW50IGNvbG9yLlxuICpcbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gQ29sb3JLZXlmcmFtZVRyYWNrKCBuYW1lLCB0aW1lcywgdmFsdWVzLCBpbnRlcnBvbGF0aW9uICkge1xuXG5cdEtleWZyYW1lVHJhY2tDb25zdHJ1Y3Rvci5jYWxsKCB0aGlzLCBuYW1lLCB0aW1lcywgdmFsdWVzLCBpbnRlcnBvbGF0aW9uICk7XG5cbn1cblxuQ29sb3JLZXlmcmFtZVRyYWNrLnByb3RvdHlwZSA9XG5cdFx0T2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggS2V5ZnJhbWVUcmFja1Byb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IENvbG9yS2V5ZnJhbWVUcmFjayxcblxuXHRWYWx1ZVR5cGVOYW1lOiAnY29sb3InXG5cblx0Ly8gVmFsdWVCdWZmZXJUeXBlIGlzIGluaGVyaXRlZFxuXG5cdC8vIERlZmF1bHRJbnRlcnBvbGF0aW9uIGlzIGluaGVyaXRlZFxuXG5cblx0Ly8gTm90ZTogVmVyeSBiYXNpYyBpbXBsZW1lbnRhdGlvbiBhbmQgbm90aGluZyBzcGVjaWFsIHlldC5cblx0Ly8gSG93ZXZlciwgdGhpcyBpcyB0aGUgcGxhY2UgZm9yIGNvbG9yIHNwYWNlIHBhcmFtZXRlcml6YXRpb24uXG5cbn0gKTtcblxuLyoqXG4gKlxuICogQSB0aW1lZCBzZXF1ZW5jZSBvZiBrZXlmcmFtZXMgZm9yIGEgc3BlY2lmaWMgcHJvcGVydHkuXG4gKlxuICpcbiAqIEBhdXRob3IgQmVuIEhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW8vXG4gKiBAYXV0aG9yIERhdmlkIFNhcm5vIC8gaHR0cDovL2xpZ2h0aGF1cy51cy9cbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBLZXlmcmFtZVRyYWNrKCBuYW1lLCB0aW1lcywgdmFsdWVzLCBpbnRlcnBvbGF0aW9uICkge1xuXG5cdEtleWZyYW1lVHJhY2tDb25zdHJ1Y3Rvci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cbn1cblxuS2V5ZnJhbWVUcmFjay5wcm90b3R5cGUgPSBLZXlmcmFtZVRyYWNrUHJvdG90eXBlO1xuS2V5ZnJhbWVUcmFja1Byb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEtleWZyYW1lVHJhY2s7XG5cbi8vIFN0YXRpYyBtZXRob2RzOlxuXG5PYmplY3QuYXNzaWduKCBLZXlmcmFtZVRyYWNrLCB7XG5cblx0Ly8gU2VyaWFsaXphdGlvbiAoaW4gc3RhdGljIGNvbnRleHQsIGJlY2F1c2Ugb2YgY29uc3RydWN0b3IgaW52b2NhdGlvblxuXHQvLyBhbmQgYXV0b21hdGljIGludm9jYXRpb24gb2YgLnRvSlNPTik6XG5cblx0cGFyc2U6IGZ1bmN0aW9uKCBqc29uICkge1xuXG5cdFx0aWYoIGpzb24udHlwZSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwidHJhY2sgdHlwZSB1bmRlZmluZWQsIGNhbiBub3QgcGFyc2VcIiApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIHRyYWNrVHlwZSA9IEtleWZyYW1lVHJhY2suX2dldFRyYWNrVHlwZUZvclZhbHVlVHlwZU5hbWUoIGpzb24udHlwZSApO1xuXG5cdFx0aWYgKCBqc29uLnRpbWVzID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHZhciB0aW1lcyA9IFtdLCB2YWx1ZXMgPSBbXTtcblxuXHRcdFx0QW5pbWF0aW9uVXRpbHMuZmxhdHRlbkpTT04oIGpzb24ua2V5cywgdGltZXMsIHZhbHVlcywgJ3ZhbHVlJyApO1xuXG5cdFx0XHRqc29uLnRpbWVzID0gdGltZXM7XG5cdFx0XHRqc29uLnZhbHVlcyA9IHZhbHVlcztcblxuXHRcdH1cblxuXHRcdC8vIGRlcml2ZWQgY2xhc3NlcyBjYW4gZGVmaW5lIGEgc3RhdGljIHBhcnNlIG1ldGhvZFxuXHRcdGlmICggdHJhY2tUeXBlLnBhcnNlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHJldHVybiB0cmFja1R5cGUucGFyc2UoIGpzb24gKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIGJ5IGRlZmF1bHQsIHdlIGFzc3N1bWUgYSBjb25zdHJ1Y3RvciBjb21wYXRpYmxlIHdpdGggdGhlIGJhc2Vcblx0XHRcdHJldHVybiBuZXcgdHJhY2tUeXBlKFxuXHRcdFx0XHRcdGpzb24ubmFtZSwganNvbi50aW1lcywganNvbi52YWx1ZXMsIGpzb24uaW50ZXJwb2xhdGlvbiApO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0dG9KU09OOiBmdW5jdGlvbiggdHJhY2sgKSB7XG5cblx0XHR2YXIgdHJhY2tUeXBlID0gdHJhY2suY29uc3RydWN0b3I7XG5cblx0XHR2YXIganNvbjtcblxuXHRcdC8vIGRlcml2ZWQgY2xhc3NlcyBjYW4gZGVmaW5lIGEgc3RhdGljIHRvSlNPTiBtZXRob2Rcblx0XHRpZiAoIHRyYWNrVHlwZS50b0pTT04gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0anNvbiA9IHRyYWNrVHlwZS50b0pTT04oIHRyYWNrICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBieSBkZWZhdWx0LCB3ZSBhc3N1bWUgdGhlIGRhdGEgY2FuIGJlIHNlcmlhbGl6ZWQgYXMtaXNcblx0XHRcdGpzb24gPSB7XG5cblx0XHRcdFx0J25hbWUnOiB0cmFjay5uYW1lLFxuXHRcdFx0XHQndGltZXMnOiBBbmltYXRpb25VdGlscy5jb252ZXJ0QXJyYXkoIHRyYWNrLnRpbWVzLCBBcnJheSApLFxuXHRcdFx0XHQndmFsdWVzJzogQW5pbWF0aW9uVXRpbHMuY29udmVydEFycmF5KCB0cmFjay52YWx1ZXMsIEFycmF5IClcblxuXHRcdFx0fTtcblxuXHRcdFx0dmFyIGludGVycG9sYXRpb24gPSB0cmFjay5nZXRJbnRlcnBvbGF0aW9uKCk7XG5cblx0XHRcdGlmICggaW50ZXJwb2xhdGlvbiAhPT0gdHJhY2suRGVmYXVsdEludGVycG9sYXRpb24gKSB7XG5cblx0XHRcdFx0anNvbi5pbnRlcnBvbGF0aW9uID0gaW50ZXJwb2xhdGlvbjtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0anNvbi50eXBlID0gdHJhY2suVmFsdWVUeXBlTmFtZTsgLy8gbWFuZGF0b3J5XG5cblx0XHRyZXR1cm4ganNvbjtcblxuXHR9LFxuXG5cdF9nZXRUcmFja1R5cGVGb3JWYWx1ZVR5cGVOYW1lOiBmdW5jdGlvbiggdHlwZU5hbWUgKSB7XG5cblx0XHRzd2l0Y2goIHR5cGVOYW1lLnRvTG93ZXJDYXNlKCkgKSB7XG5cblx0XHRcdGNhc2UgXCJzY2FsYXJcIjpcblx0XHRcdGNhc2UgXCJkb3VibGVcIjpcblx0XHRcdGNhc2UgXCJmbG9hdFwiOlxuXHRcdFx0Y2FzZSBcIm51bWJlclwiOlxuXHRcdFx0Y2FzZSBcImludGVnZXJcIjpcblxuXHRcdFx0XHRyZXR1cm4gTnVtYmVyS2V5ZnJhbWVUcmFjaztcblxuXHRcdFx0Y2FzZSBcInZlY3RvclwiOlxuXHRcdFx0Y2FzZSBcInZlY3RvcjJcIjpcblx0XHRcdGNhc2UgXCJ2ZWN0b3IzXCI6XG5cdFx0XHRjYXNlIFwidmVjdG9yNFwiOlxuXG5cdFx0XHRcdHJldHVybiBWZWN0b3JLZXlmcmFtZVRyYWNrO1xuXG5cdFx0XHRjYXNlIFwiY29sb3JcIjpcblxuXHRcdFx0XHRyZXR1cm4gQ29sb3JLZXlmcmFtZVRyYWNrO1xuXG5cdFx0XHRjYXNlIFwicXVhdGVybmlvblwiOlxuXG5cdFx0XHRcdHJldHVybiBRdWF0ZXJuaW9uS2V5ZnJhbWVUcmFjaztcblxuXHRcdFx0Y2FzZSBcImJvb2xcIjpcblx0XHRcdGNhc2UgXCJib29sZWFuXCI6XG5cblx0XHRcdFx0cmV0dXJuIEJvb2xlYW5LZXlmcmFtZVRyYWNrO1xuXG5cdFx0XHRjYXNlIFwic3RyaW5nXCI6XG5cblx0XHRcdFx0cmV0dXJuIFN0cmluZ0tleWZyYW1lVHJhY2s7XG5cblx0XHR9XG5cblx0XHR0aHJvdyBuZXcgRXJyb3IoIFwiVW5zdXBwb3J0ZWQgdHlwZU5hbWU6IFwiICsgdHlwZU5hbWUgKTtcblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKlxuICogUmV1c2FibGUgc2V0IG9mIFRyYWNrcyB0aGF0IHJlcHJlc2VudCBhbiBhbmltYXRpb24uXG4gKlxuICogQGF1dGhvciBCZW4gSG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pby9cbiAqIEBhdXRob3IgRGF2aWQgU2Fybm8gLyBodHRwOi8vbGlnaHRoYXVzLnVzL1xuICovXG5cbmZ1bmN0aW9uIEFuaW1hdGlvbkNsaXAoIG5hbWUsIGR1cmF0aW9uLCB0cmFja3MgKSB7XG5cblx0dGhpcy5uYW1lID0gbmFtZTtcblx0dGhpcy50cmFja3MgPSB0cmFja3M7XG5cdHRoaXMuZHVyYXRpb24gPSAoIGR1cmF0aW9uICE9PSB1bmRlZmluZWQgKSA/IGR1cmF0aW9uIDogLSAxO1xuXG5cdHRoaXMudXVpZCA9IF9NYXRoLmdlbmVyYXRlVVVJRCgpO1xuXG5cdC8vIHRoaXMgbWVhbnMgaXQgc2hvdWxkIGZpZ3VyZSBvdXQgaXRzIGR1cmF0aW9uIGJ5IHNjYW5uaW5nIHRoZSB0cmFja3Ncblx0aWYgKCB0aGlzLmR1cmF0aW9uIDwgMCApIHtcblxuXHRcdHRoaXMucmVzZXREdXJhdGlvbigpO1xuXG5cdH1cblxuXHR0aGlzLm9wdGltaXplKCk7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQW5pbWF0aW9uQ2xpcCwge1xuXG5cdHBhcnNlOiBmdW5jdGlvbiAoIGpzb24gKSB7XG5cblx0XHR2YXIgdHJhY2tzID0gW10sXG5cdFx0XHRqc29uVHJhY2tzID0ganNvbi50cmFja3MsXG5cdFx0XHRmcmFtZVRpbWUgPSAxLjAgLyAoIGpzb24uZnBzIHx8IDEuMCApO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBuID0ganNvblRyYWNrcy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdHRyYWNrcy5wdXNoKCBLZXlmcmFtZVRyYWNrLnBhcnNlKCBqc29uVHJhY2tzWyBpIF0gKS5zY2FsZSggZnJhbWVUaW1lICkgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgQW5pbWF0aW9uQ2xpcCgganNvbi5uYW1lLCBqc29uLmR1cmF0aW9uLCB0cmFja3MgKTtcblxuXHR9LFxuXG5cdHRvSlNPTjogZnVuY3Rpb24gKCBjbGlwICkge1xuXG5cdFx0dmFyIHRyYWNrcyA9IFtdLFxuXHRcdFx0Y2xpcFRyYWNrcyA9IGNsaXAudHJhY2tzO1xuXG5cdFx0dmFyIGpzb24gPSB7XG5cblx0XHRcdCduYW1lJzogY2xpcC5uYW1lLFxuXHRcdFx0J2R1cmF0aW9uJzogY2xpcC5kdXJhdGlvbixcblx0XHRcdCd0cmFja3MnOiB0cmFja3NcblxuXHRcdH07XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBjbGlwVHJhY2tzLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdFx0dHJhY2tzLnB1c2goIEtleWZyYW1lVHJhY2sudG9KU09OKCBjbGlwVHJhY2tzWyBpIF0gKSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpzb247XG5cblx0fSxcblxuXHRDcmVhdGVGcm9tTW9ycGhUYXJnZXRTZXF1ZW5jZTogZnVuY3Rpb24gKCBuYW1lLCBtb3JwaFRhcmdldFNlcXVlbmNlLCBmcHMsIG5vTG9vcCApIHtcblxuXHRcdHZhciBudW1Nb3JwaFRhcmdldHMgPSBtb3JwaFRhcmdldFNlcXVlbmNlLmxlbmd0aDtcblx0XHR2YXIgdHJhY2tzID0gW107XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBudW1Nb3JwaFRhcmdldHM7IGkgKysgKSB7XG5cblx0XHRcdHZhciB0aW1lcyA9IFtdO1xuXHRcdFx0dmFyIHZhbHVlcyA9IFtdO1xuXG5cdFx0XHR0aW1lcy5wdXNoKFxuXHRcdFx0XHRcdCggaSArIG51bU1vcnBoVGFyZ2V0cyAtIDEgKSAlIG51bU1vcnBoVGFyZ2V0cyxcblx0XHRcdFx0XHRpLFxuXHRcdFx0XHRcdCggaSArIDEgKSAlIG51bU1vcnBoVGFyZ2V0cyApO1xuXG5cdFx0XHR2YWx1ZXMucHVzaCggMCwgMSwgMCApO1xuXG5cdFx0XHR2YXIgb3JkZXIgPSBBbmltYXRpb25VdGlscy5nZXRLZXlmcmFtZU9yZGVyKCB0aW1lcyApO1xuXHRcdFx0dGltZXMgPSBBbmltYXRpb25VdGlscy5zb3J0ZWRBcnJheSggdGltZXMsIDEsIG9yZGVyICk7XG5cdFx0XHR2YWx1ZXMgPSBBbmltYXRpb25VdGlscy5zb3J0ZWRBcnJheSggdmFsdWVzLCAxLCBvcmRlciApO1xuXG5cdFx0XHQvLyBpZiB0aGVyZSBpcyBhIGtleSBhdCB0aGUgZmlyc3QgZnJhbWUsIGR1cGxpY2F0ZSBpdCBhcyB0aGVcblx0XHRcdC8vIGxhc3QgZnJhbWUgYXMgd2VsbCBmb3IgcGVyZmVjdCBsb29wLlxuXHRcdFx0aWYgKCAhIG5vTG9vcCAmJiB0aW1lc1sgMCBdID09PSAwICkge1xuXG5cdFx0XHRcdHRpbWVzLnB1c2goIG51bU1vcnBoVGFyZ2V0cyApO1xuXHRcdFx0XHR2YWx1ZXMucHVzaCggdmFsdWVzWyAwIF0gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0cmFja3MucHVzaChcblx0XHRcdFx0XHRuZXcgTnVtYmVyS2V5ZnJhbWVUcmFjayhcblx0XHRcdFx0XHRcdCcubW9ycGhUYXJnZXRJbmZsdWVuY2VzWycgKyBtb3JwaFRhcmdldFNlcXVlbmNlWyBpIF0ubmFtZSArICddJyxcblx0XHRcdFx0XHRcdHRpbWVzLCB2YWx1ZXNcblx0XHRcdFx0XHQpLnNjYWxlKCAxLjAgLyBmcHMgKSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBBbmltYXRpb25DbGlwKCBuYW1lLCAtIDEsIHRyYWNrcyApO1xuXG5cdH0sXG5cblx0ZmluZEJ5TmFtZTogZnVuY3Rpb24gKCBvYmplY3RPckNsaXBBcnJheSwgbmFtZSApIHtcblxuXHRcdHZhciBjbGlwQXJyYXkgPSBvYmplY3RPckNsaXBBcnJheTtcblxuXHRcdGlmICggISBBcnJheS5pc0FycmF5KCBvYmplY3RPckNsaXBBcnJheSApICkge1xuXG5cdFx0XHR2YXIgbyA9IG9iamVjdE9yQ2xpcEFycmF5O1xuXHRcdFx0Y2xpcEFycmF5ID0gby5nZW9tZXRyeSAmJiBvLmdlb21ldHJ5LmFuaW1hdGlvbnMgfHwgby5hbmltYXRpb25zO1xuXG5cdFx0fVxuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY2xpcEFycmF5Lmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0aWYgKCBjbGlwQXJyYXlbIGkgXS5uYW1lID09PSBuYW1lICkge1xuXG5cdFx0XHRcdHJldHVybiBjbGlwQXJyYXlbIGkgXTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cblx0fSxcblxuXHRDcmVhdGVDbGlwc0Zyb21Nb3JwaFRhcmdldFNlcXVlbmNlczogZnVuY3Rpb24gKCBtb3JwaFRhcmdldHMsIGZwcywgbm9Mb29wICkge1xuXG5cdFx0dmFyIGFuaW1hdGlvblRvTW9ycGhUYXJnZXRzID0ge307XG5cblx0XHQvLyB0ZXN0ZWQgd2l0aCBodHRwczovL3JlZ2V4MTAxLmNvbS8gb24gdHJpY2sgc2VxdWVuY2VzXG5cdFx0Ly8gc3VjaCBmbGFtaW5nb19mbHlBXzAwMywgZmxhbWluZ29fcnVuMV8wMDMsIGNyZGVhdGgwMDU5XG5cdFx0dmFyIHBhdHRlcm4gPSAvXihbXFx3LV0qPykoW1xcZF0rKSQvO1xuXG5cdFx0Ly8gc29ydCBtb3JwaCB0YXJnZXQgbmFtZXMgaW50byBhbmltYXRpb24gZ3JvdXBzIGJhc2VkXG5cdFx0Ly8gcGF0dGVybnMgbGlrZSBXYWxrXzAwMSwgV2Fsa18wMDIsIFJ1bl8wMDEsIFJ1bl8wMDJcblx0XHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gbW9ycGhUYXJnZXRzLmxlbmd0aDsgaSA8IGlsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgbW9ycGhUYXJnZXQgPSBtb3JwaFRhcmdldHNbIGkgXTtcblx0XHRcdHZhciBwYXJ0cyA9IG1vcnBoVGFyZ2V0Lm5hbWUubWF0Y2goIHBhdHRlcm4gKTtcblxuXHRcdFx0aWYgKCBwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAxICkge1xuXG5cdFx0XHRcdHZhciBuYW1lID0gcGFydHNbIDEgXTtcblxuXHRcdFx0XHR2YXIgYW5pbWF0aW9uTW9ycGhUYXJnZXRzID0gYW5pbWF0aW9uVG9Nb3JwaFRhcmdldHNbIG5hbWUgXTtcblx0XHRcdFx0aWYgKCAhIGFuaW1hdGlvbk1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0XHRcdGFuaW1hdGlvblRvTW9ycGhUYXJnZXRzWyBuYW1lIF0gPSBhbmltYXRpb25Nb3JwaFRhcmdldHMgPSBbXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0YW5pbWF0aW9uTW9ycGhUYXJnZXRzLnB1c2goIG1vcnBoVGFyZ2V0ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHZhciBjbGlwcyA9IFtdO1xuXG5cdFx0Zm9yICggdmFyIG5hbWUgaW4gYW5pbWF0aW9uVG9Nb3JwaFRhcmdldHMgKSB7XG5cblx0XHRcdGNsaXBzLnB1c2goIEFuaW1hdGlvbkNsaXAuQ3JlYXRlRnJvbU1vcnBoVGFyZ2V0U2VxdWVuY2UoIG5hbWUsIGFuaW1hdGlvblRvTW9ycGhUYXJnZXRzWyBuYW1lIF0sIGZwcywgbm9Mb29wICkgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiBjbGlwcztcblxuXHR9LFxuXG5cdC8vIHBhcnNlIHRoZSBhbmltYXRpb24uaGllcmFyY2h5IGZvcm1hdFxuXHRwYXJzZUFuaW1hdGlvbjogZnVuY3Rpb24gKCBhbmltYXRpb24sIGJvbmVzICkge1xuXG5cdFx0aWYgKCAhIGFuaW1hdGlvbiApIHtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggXCIgIG5vIGFuaW1hdGlvbiBpbiBKU09OTG9hZGVyIGRhdGFcIiApO1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHR9XG5cblx0XHR2YXIgYWRkTm9uZW1wdHlUcmFjayA9IGZ1bmN0aW9uICggdHJhY2tUeXBlLCB0cmFja05hbWUsIGFuaW1hdGlvbktleXMsIHByb3BlcnR5TmFtZSwgZGVzdFRyYWNrcyApIHtcblxuXHRcdFx0Ly8gb25seSByZXR1cm4gdHJhY2sgaWYgdGhlcmUgYXJlIGFjdHVhbGx5IGtleXMuXG5cdFx0XHRpZiAoIGFuaW1hdGlvbktleXMubGVuZ3RoICE9PSAwICkge1xuXG5cdFx0XHRcdHZhciB0aW1lcyA9IFtdO1xuXHRcdFx0XHR2YXIgdmFsdWVzID0gW107XG5cblx0XHRcdFx0QW5pbWF0aW9uVXRpbHMuZmxhdHRlbkpTT04oIGFuaW1hdGlvbktleXMsIHRpbWVzLCB2YWx1ZXMsIHByb3BlcnR5TmFtZSApO1xuXG5cdFx0XHRcdC8vIGVtcHR5IGtleXMgYXJlIGZpbHRlcmVkIG91dCwgc28gY2hlY2sgYWdhaW5cblx0XHRcdFx0aWYgKCB0aW1lcy5sZW5ndGggIT09IDAgKSB7XG5cblx0XHRcdFx0XHRkZXN0VHJhY2tzLnB1c2goIG5ldyB0cmFja1R5cGUoIHRyYWNrTmFtZSwgdGltZXMsIHZhbHVlcyApICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dmFyIHRyYWNrcyA9IFtdO1xuXG5cdFx0dmFyIGNsaXBOYW1lID0gYW5pbWF0aW9uLm5hbWUgfHwgJ2RlZmF1bHQnO1xuXHRcdC8vIGF1dG9tYXRpYyBsZW5ndGggZGV0ZXJtaW5hdGlvbiBpbiBBbmltYXRpb25DbGlwLlxuXHRcdHZhciBkdXJhdGlvbiA9IGFuaW1hdGlvbi5sZW5ndGggfHwgLSAxO1xuXHRcdHZhciBmcHMgPSBhbmltYXRpb24uZnBzIHx8IDMwO1xuXG5cdFx0dmFyIGhpZXJhcmNoeVRyYWNrcyA9IGFuaW1hdGlvbi5oaWVyYXJjaHkgfHwgW107XG5cblx0XHRmb3IgKCB2YXIgaCA9IDA7IGggPCBoaWVyYXJjaHlUcmFja3MubGVuZ3RoOyBoICsrICkge1xuXG5cdFx0XHR2YXIgYW5pbWF0aW9uS2V5cyA9IGhpZXJhcmNoeVRyYWNrc1sgaCBdLmtleXM7XG5cblx0XHRcdC8vIHNraXAgZW1wdHkgdHJhY2tzXG5cdFx0XHRpZiAoICEgYW5pbWF0aW9uS2V5cyB8fCBhbmltYXRpb25LZXlzLmxlbmd0aCA9PT0gMCApIGNvbnRpbnVlO1xuXG5cdFx0XHQvLyBwcm9jZXNzIG1vcnBoIHRhcmdldHMgaW4gYSB3YXkgZXhhY3RseSBjb21wYXRpYmxlXG5cdFx0XHQvLyB3aXRoIEFuaW1hdGlvbkhhbmRsZXIuaW5pdCggYW5pbWF0aW9uIClcblx0XHRcdGlmICggYW5pbWF0aW9uS2V5c1sgMCBdLm1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0XHQvLyBmaWd1cmUgb3V0IGFsbCBtb3JwaCB0YXJnZXRzIHVzZWQgaW4gdGhpcyB0cmFja1xuXHRcdFx0XHR2YXIgbW9ycGhUYXJnZXROYW1lcyA9IHt9O1xuXG5cdFx0XHRcdGZvciAoIHZhciBrID0gMDsgayA8IGFuaW1hdGlvbktleXMubGVuZ3RoOyBrICsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCBhbmltYXRpb25LZXlzWyBrIF0ubW9ycGhUYXJnZXRzICkge1xuXG5cdFx0XHRcdFx0XHRmb3IgKCB2YXIgbSA9IDA7IG0gPCBhbmltYXRpb25LZXlzWyBrIF0ubW9ycGhUYXJnZXRzLmxlbmd0aDsgbSArKyApIHtcblxuXHRcdFx0XHRcdFx0XHRtb3JwaFRhcmdldE5hbWVzWyBhbmltYXRpb25LZXlzWyBrIF0ubW9ycGhUYXJnZXRzWyBtIF0gXSA9IC0gMTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBjcmVhdGUgYSB0cmFjayBmb3IgZWFjaCBtb3JwaCB0YXJnZXQgd2l0aCBhbGwgemVyb1xuXHRcdFx0XHQvLyBtb3JwaFRhcmdldEluZmx1ZW5jZXMgZXhjZXB0IGZvciB0aGUga2V5cyBpbiB3aGljaFxuXHRcdFx0XHQvLyB0aGUgbW9ycGhUYXJnZXQgaXMgbmFtZWQuXG5cdFx0XHRcdGZvciAoIHZhciBtb3JwaFRhcmdldE5hbWUgaW4gbW9ycGhUYXJnZXROYW1lcyApIHtcblxuXHRcdFx0XHRcdHZhciB0aW1lcyA9IFtdO1xuXHRcdFx0XHRcdHZhciB2YWx1ZXMgPSBbXTtcblxuXHRcdFx0XHRcdGZvciAoIHZhciBtID0gMDsgbSAhPT0gYW5pbWF0aW9uS2V5c1sgayBdLm1vcnBoVGFyZ2V0cy5sZW5ndGg7ICsrIG0gKSB7XG5cblx0XHRcdFx0XHRcdHZhciBhbmltYXRpb25LZXkgPSBhbmltYXRpb25LZXlzWyBrIF07XG5cblx0XHRcdFx0XHRcdHRpbWVzLnB1c2goIGFuaW1hdGlvbktleS50aW1lICk7XG5cdFx0XHRcdFx0XHR2YWx1ZXMucHVzaCggKCBhbmltYXRpb25LZXkubW9ycGhUYXJnZXQgPT09IG1vcnBoVGFyZ2V0TmFtZSApID8gMSA6IDAgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHRyYWNrcy5wdXNoKCBuZXcgTnVtYmVyS2V5ZnJhbWVUcmFjayggJy5tb3JwaFRhcmdldEluZmx1ZW5jZVsnICsgbW9ycGhUYXJnZXROYW1lICsgJ10nLCB0aW1lcywgdmFsdWVzICkgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZHVyYXRpb24gPSBtb3JwaFRhcmdldE5hbWVzLmxlbmd0aCAqICggZnBzIHx8IDEuMCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIC4uLmFzc3VtZSBza2VsZXRhbCBhbmltYXRpb25cblxuXHRcdFx0XHR2YXIgYm9uZU5hbWUgPSAnLmJvbmVzWycgKyBib25lc1sgaCBdLm5hbWUgKyAnXSc7XG5cblx0XHRcdFx0YWRkTm9uZW1wdHlUcmFjayhcblx0XHRcdFx0XHRcdFZlY3RvcktleWZyYW1lVHJhY2ssIGJvbmVOYW1lICsgJy5wb3NpdGlvbicsXG5cdFx0XHRcdFx0XHRhbmltYXRpb25LZXlzLCAncG9zJywgdHJhY2tzICk7XG5cblx0XHRcdFx0YWRkTm9uZW1wdHlUcmFjayhcblx0XHRcdFx0XHRcdFF1YXRlcm5pb25LZXlmcmFtZVRyYWNrLCBib25lTmFtZSArICcucXVhdGVybmlvbicsXG5cdFx0XHRcdFx0XHRhbmltYXRpb25LZXlzLCAncm90JywgdHJhY2tzICk7XG5cblx0XHRcdFx0YWRkTm9uZW1wdHlUcmFjayhcblx0XHRcdFx0XHRcdFZlY3RvcktleWZyYW1lVHJhY2ssIGJvbmVOYW1lICsgJy5zY2FsZScsXG5cdFx0XHRcdFx0XHRhbmltYXRpb25LZXlzLCAnc2NsJywgdHJhY2tzICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggdHJhY2tzLmxlbmd0aCA9PT0gMCApIHtcblxuXHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHR9XG5cblx0XHR2YXIgY2xpcCA9IG5ldyBBbmltYXRpb25DbGlwKCBjbGlwTmFtZSwgZHVyYXRpb24sIHRyYWNrcyApO1xuXG5cdFx0cmV0dXJuIGNsaXA7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIEFuaW1hdGlvbkNsaXAucHJvdG90eXBlLCB7XG5cblx0cmVzZXREdXJhdGlvbjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHRyYWNrcyA9IHRoaXMudHJhY2tzLCBkdXJhdGlvbiA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSB0cmFja3MubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHR2YXIgdHJhY2sgPSB0aGlzLnRyYWNrc1sgaSBdO1xuXG5cdFx0XHRkdXJhdGlvbiA9IE1hdGgubWF4KCBkdXJhdGlvbiwgdHJhY2sudGltZXNbIHRyYWNrLnRpbWVzLmxlbmd0aCAtIDEgXSApO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuXG5cdH0sXG5cblx0dHJpbTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy50cmFja3MubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLnRyYWNrc1sgaSBdLnRyaW0oIDAsIHRoaXMuZHVyYXRpb24gKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0b3B0aW1pemU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMudHJhY2tzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0dGhpcy50cmFja3NbIGkgXS5vcHRpbWl6ZSgpO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBNYXRlcmlhbExvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblx0dGhpcy50ZXh0dXJlcyA9IHt9O1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIE1hdGVyaWFsTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGxvYWRlciA9IG5ldyBGaWxlTG9hZGVyKCBzY29wZS5tYW5hZ2VyICk7XG5cdFx0bG9hZGVyLnNldFJlc3BvbnNlVHlwZSggJ2pzb24nICk7XG5cdFx0bG9hZGVyLmxvYWQoIHVybCwgZnVuY3Rpb24gKCBqc29uICkge1xuXG5cdFx0XHRvbkxvYWQoIHNjb3BlLnBhcnNlKCBqc29uICkgKTtcblxuXHRcdH0sIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKTtcblxuXHR9LFxuXG5cdHNldFRleHR1cmVzOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy50ZXh0dXJlcyA9IHZhbHVlO1xuXG5cdH0sXG5cblx0cGFyc2U6IGZ1bmN0aW9uICgganNvbiApIHtcblxuXHRcdHZhciB0ZXh0dXJlcyA9IHRoaXMudGV4dHVyZXM7XG5cblx0XHRmdW5jdGlvbiBnZXRUZXh0dXJlKCBuYW1lICkge1xuXG5cdFx0XHRpZiAoIHRleHR1cmVzWyBuYW1lIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRlcmlhbExvYWRlcjogVW5kZWZpbmVkIHRleHR1cmUnLCBuYW1lICk7XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRleHR1cmVzWyBuYW1lIF07XG5cblx0XHR9XG5cblx0XHR2YXIgbWF0ZXJpYWwgPSBuZXcgTWF0ZXJpYWxzWyBqc29uLnR5cGUgXSgpO1xuXG5cdFx0aWYgKCBqc29uLnV1aWQgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnV1aWQgPSBqc29uLnV1aWQ7XG5cdFx0aWYgKCBqc29uLm5hbWUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLm5hbWUgPSBqc29uLm5hbWU7XG5cdFx0aWYgKCBqc29uLmNvbG9yICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5jb2xvci5zZXRIZXgoIGpzb24uY29sb3IgKTtcblx0XHRpZiAoIGpzb24ucm91Z2huZXNzICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5yb3VnaG5lc3MgPSBqc29uLnJvdWdobmVzcztcblx0XHRpZiAoIGpzb24ubWV0YWxuZXNzICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5tZXRhbG5lc3MgPSBqc29uLm1ldGFsbmVzcztcblx0XHRpZiAoIGpzb24uZW1pc3NpdmUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmVtaXNzaXZlLnNldEhleCgganNvbi5lbWlzc2l2ZSApO1xuXHRcdGlmICgganNvbi5zcGVjdWxhciAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuc3BlY3VsYXIuc2V0SGV4KCBqc29uLnNwZWN1bGFyICk7XG5cdFx0aWYgKCBqc29uLnNoaW5pbmVzcyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuc2hpbmluZXNzID0ganNvbi5zaGluaW5lc3M7XG5cdFx0aWYgKCBqc29uLmNsZWFyQ29hdCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuY2xlYXJDb2F0ID0ganNvbi5jbGVhckNvYXQ7XG5cdFx0aWYgKCBqc29uLmNsZWFyQ29hdFJvdWdobmVzcyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuY2xlYXJDb2F0Um91Z2huZXNzID0ganNvbi5jbGVhckNvYXRSb3VnaG5lc3M7XG5cdFx0aWYgKCBqc29uLnVuaWZvcm1zICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC51bmlmb3JtcyA9IGpzb24udW5pZm9ybXM7XG5cdFx0aWYgKCBqc29uLnZlcnRleFNoYWRlciAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwudmVydGV4U2hhZGVyID0ganNvbi52ZXJ0ZXhTaGFkZXI7XG5cdFx0aWYgKCBqc29uLmZyYWdtZW50U2hhZGVyICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5mcmFnbWVudFNoYWRlciA9IGpzb24uZnJhZ21lbnRTaGFkZXI7XG5cdFx0aWYgKCBqc29uLnZlcnRleENvbG9ycyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwudmVydGV4Q29sb3JzID0ganNvbi52ZXJ0ZXhDb2xvcnM7XG5cdFx0aWYgKCBqc29uLmZvZyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZm9nID0ganNvbi5mb2c7XG5cdFx0aWYgKCBqc29uLnNoYWRpbmcgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnNoYWRpbmcgPSBqc29uLnNoYWRpbmc7XG5cdFx0aWYgKCBqc29uLmJsZW5kaW5nICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5ibGVuZGluZyA9IGpzb24uYmxlbmRpbmc7XG5cdFx0aWYgKCBqc29uLnNpZGUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnNpZGUgPSBqc29uLnNpZGU7XG5cdFx0aWYgKCBqc29uLm9wYWNpdHkgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLm9wYWNpdHkgPSBqc29uLm9wYWNpdHk7XG5cdFx0aWYgKCBqc29uLnRyYW5zcGFyZW50ICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC50cmFuc3BhcmVudCA9IGpzb24udHJhbnNwYXJlbnQ7XG5cdFx0aWYgKCBqc29uLmFscGhhVGVzdCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuYWxwaGFUZXN0ID0ganNvbi5hbHBoYVRlc3Q7XG5cdFx0aWYgKCBqc29uLmRlcHRoVGVzdCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZGVwdGhUZXN0ID0ganNvbi5kZXB0aFRlc3Q7XG5cdFx0aWYgKCBqc29uLmRlcHRoV3JpdGUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmRlcHRoV3JpdGUgPSBqc29uLmRlcHRoV3JpdGU7XG5cdFx0aWYgKCBqc29uLmNvbG9yV3JpdGUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmNvbG9yV3JpdGUgPSBqc29uLmNvbG9yV3JpdGU7XG5cdFx0aWYgKCBqc29uLndpcmVmcmFtZSAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwud2lyZWZyYW1lID0ganNvbi53aXJlZnJhbWU7XG5cdFx0aWYgKCBqc29uLndpcmVmcmFtZUxpbmV3aWR0aCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwud2lyZWZyYW1lTGluZXdpZHRoID0ganNvbi53aXJlZnJhbWVMaW5ld2lkdGg7XG5cdFx0aWYgKCBqc29uLndpcmVmcmFtZUxpbmVjYXAgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLndpcmVmcmFtZUxpbmVjYXAgPSBqc29uLndpcmVmcmFtZUxpbmVjYXA7XG5cdFx0aWYgKCBqc29uLndpcmVmcmFtZUxpbmVqb2luICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC53aXJlZnJhbWVMaW5lam9pbiA9IGpzb24ud2lyZWZyYW1lTGluZWpvaW47XG5cdFx0aWYgKCBqc29uLnNraW5uaW5nICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5za2lubmluZyA9IGpzb24uc2tpbm5pbmc7XG5cdFx0aWYgKCBqc29uLm1vcnBoVGFyZ2V0cyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwubW9ycGhUYXJnZXRzID0ganNvbi5tb3JwaFRhcmdldHM7XG5cblx0XHQvLyBmb3IgUG9pbnRzTWF0ZXJpYWxcblxuXHRcdGlmICgganNvbi5zaXplICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5zaXplID0ganNvbi5zaXplO1xuXHRcdGlmICgganNvbi5zaXplQXR0ZW51YXRpb24gIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnNpemVBdHRlbnVhdGlvbiA9IGpzb24uc2l6ZUF0dGVudWF0aW9uO1xuXG5cdFx0Ly8gbWFwc1xuXG5cdFx0aWYgKCBqc29uLm1hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwubWFwID0gZ2V0VGV4dHVyZSgganNvbi5tYXAgKTtcblxuXHRcdGlmICgganNvbi5hbHBoYU1hcCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRtYXRlcmlhbC5hbHBoYU1hcCA9IGdldFRleHR1cmUoIGpzb24uYWxwaGFNYXAgKTtcblx0XHRcdG1hdGVyaWFsLnRyYW5zcGFyZW50ID0gdHJ1ZTtcblxuXHRcdH1cblxuXHRcdGlmICgganNvbi5idW1wTWFwICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5idW1wTWFwID0gZ2V0VGV4dHVyZSgganNvbi5idW1wTWFwICk7XG5cdFx0aWYgKCBqc29uLmJ1bXBTY2FsZSAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuYnVtcFNjYWxlID0ganNvbi5idW1wU2NhbGU7XG5cblx0XHRpZiAoIGpzb24ubm9ybWFsTWFwICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5ub3JtYWxNYXAgPSBnZXRUZXh0dXJlKCBqc29uLm5vcm1hbE1hcCApO1xuXHRcdGlmICgganNvbi5ub3JtYWxTY2FsZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgbm9ybWFsU2NhbGUgPSBqc29uLm5vcm1hbFNjYWxlO1xuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG5vcm1hbFNjYWxlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdC8vIEJsZW5kZXIgZXhwb3J0ZXIgdXNlZCB0byBleHBvcnQgYSBzY2FsYXIuIFNlZSAjNzQ1OVxuXG5cdFx0XHRcdG5vcm1hbFNjYWxlID0gWyBub3JtYWxTY2FsZSwgbm9ybWFsU2NhbGUgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRtYXRlcmlhbC5ub3JtYWxTY2FsZSA9IG5ldyBWZWN0b3IyKCkuZnJvbUFycmF5KCBub3JtYWxTY2FsZSApO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCBqc29uLmRpc3BsYWNlbWVudE1hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZGlzcGxhY2VtZW50TWFwID0gZ2V0VGV4dHVyZSgganNvbi5kaXNwbGFjZW1lbnRNYXAgKTtcblx0XHRpZiAoIGpzb24uZGlzcGxhY2VtZW50U2NhbGUgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmRpc3BsYWNlbWVudFNjYWxlID0ganNvbi5kaXNwbGFjZW1lbnRTY2FsZTtcblx0XHRpZiAoIGpzb24uZGlzcGxhY2VtZW50QmlhcyAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZGlzcGxhY2VtZW50QmlhcyA9IGpzb24uZGlzcGxhY2VtZW50QmlhcztcblxuXHRcdGlmICgganNvbi5yb3VnaG5lc3NNYXAgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnJvdWdobmVzc01hcCA9IGdldFRleHR1cmUoIGpzb24ucm91Z2huZXNzTWFwICk7XG5cdFx0aWYgKCBqc29uLm1ldGFsbmVzc01hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwubWV0YWxuZXNzTWFwID0gZ2V0VGV4dHVyZSgganNvbi5tZXRhbG5lc3NNYXAgKTtcblxuXHRcdGlmICgganNvbi5lbWlzc2l2ZU1hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZW1pc3NpdmVNYXAgPSBnZXRUZXh0dXJlKCBqc29uLmVtaXNzaXZlTWFwICk7XG5cdFx0aWYgKCBqc29uLmVtaXNzaXZlSW50ZW5zaXR5ICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5lbWlzc2l2ZUludGVuc2l0eSA9IGpzb24uZW1pc3NpdmVJbnRlbnNpdHk7XG5cblx0XHRpZiAoIGpzb24uc3BlY3VsYXJNYXAgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnNwZWN1bGFyTWFwID0gZ2V0VGV4dHVyZSgganNvbi5zcGVjdWxhck1hcCApO1xuXG5cdFx0aWYgKCBqc29uLmVudk1hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuZW52TWFwID0gZ2V0VGV4dHVyZSgganNvbi5lbnZNYXAgKTtcblxuXHRcdGlmICgganNvbi5yZWZsZWN0aXZpdHkgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLnJlZmxlY3Rpdml0eSA9IGpzb24ucmVmbGVjdGl2aXR5O1xuXG5cdFx0aWYgKCBqc29uLmxpZ2h0TWFwICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5saWdodE1hcCA9IGdldFRleHR1cmUoIGpzb24ubGlnaHRNYXAgKTtcblx0XHRpZiAoIGpzb24ubGlnaHRNYXBJbnRlbnNpdHkgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmxpZ2h0TWFwSW50ZW5zaXR5ID0ganNvbi5saWdodE1hcEludGVuc2l0eTtcblxuXHRcdGlmICgganNvbi5hb01hcCAhPT0gdW5kZWZpbmVkICkgbWF0ZXJpYWwuYW9NYXAgPSBnZXRUZXh0dXJlKCBqc29uLmFvTWFwICk7XG5cdFx0aWYgKCBqc29uLmFvTWFwSW50ZW5zaXR5ICE9PSB1bmRlZmluZWQgKSBtYXRlcmlhbC5hb01hcEludGVuc2l0eSA9IGpzb24uYW9NYXBJbnRlbnNpdHk7XG5cblx0XHRpZiAoIGpzb24uZ3JhZGllbnRNYXAgIT09IHVuZGVmaW5lZCApIG1hdGVyaWFsLmdyYWRpZW50TWFwID0gZ2V0VGV4dHVyZSgganNvbi5ncmFkaWVudE1hcCApO1xuXG5cdFx0cmV0dXJuIG1hdGVyaWFsO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyR2VvbWV0cnlMb2FkZXIoIG1hbmFnZXIgKSB7XG5cblx0dGhpcy5tYW5hZ2VyID0gKCBtYW5hZ2VyICE9PSB1bmRlZmluZWQgKSA/IG1hbmFnZXIgOiBEZWZhdWx0TG9hZGluZ01hbmFnZXI7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQnVmZmVyR2VvbWV0cnlMb2FkZXIucHJvdG90eXBlLCB7XG5cblx0bG9hZDogZnVuY3Rpb24gKCB1cmwsIG9uTG9hZCwgb25Qcm9ncmVzcywgb25FcnJvciApIHtcblxuXHRcdHZhciBzY29wZSA9IHRoaXM7XG5cblx0XHR2YXIgbG9hZGVyID0gbmV3IEZpbGVMb2FkZXIoIHNjb3BlLm1hbmFnZXIgKTtcblx0XHRsb2FkZXIuc2V0UmVzcG9uc2VUeXBlKCAnanNvbicgKTtcblx0XHRsb2FkZXIubG9hZCggdXJsLCBmdW5jdGlvbiAoIGpzb24gKSB7XG5cblx0XHRcdG9uTG9hZCggc2NvcGUucGFyc2UoIGpzb24gKSApO1xuXG5cdFx0fSwgb25Qcm9ncmVzcywgb25FcnJvciApO1xuXG5cdH0sXG5cblx0cGFyc2U6IGZ1bmN0aW9uICgganNvbiApIHtcblxuXHRcdHZhciBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXG5cdFx0dmFyIGluZGV4ID0ganNvbi5kYXRhLmluZGV4O1xuXG5cdFx0aWYgKCBpbmRleCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgdHlwZWRBcnJheSA9IG5ldyBUWVBFRF9BUlJBWVNbIGluZGV4LnR5cGUgXSggaW5kZXguYXJyYXkgKTtcblx0XHRcdGdlb21ldHJ5LnNldEluZGV4KCBuZXcgQnVmZmVyQXR0cmlidXRlKCB0eXBlZEFycmF5LCAxICkgKTtcblxuXHRcdH1cblxuXHRcdHZhciBhdHRyaWJ1dGVzID0ganNvbi5kYXRhLmF0dHJpYnV0ZXM7XG5cblx0XHRmb3IgKCB2YXIga2V5IGluIGF0dHJpYnV0ZXMgKSB7XG5cblx0XHRcdHZhciBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGVzWyBrZXkgXTtcblx0XHRcdHZhciB0eXBlZEFycmF5ID0gbmV3IFRZUEVEX0FSUkFZU1sgYXR0cmlidXRlLnR5cGUgXSggYXR0cmlidXRlLmFycmF5ICk7XG5cblx0XHRcdGdlb21ldHJ5LmFkZEF0dHJpYnV0ZSgga2V5LCBuZXcgQnVmZmVyQXR0cmlidXRlKCB0eXBlZEFycmF5LCBhdHRyaWJ1dGUuaXRlbVNpemUsIGF0dHJpYnV0ZS5ub3JtYWxpemVkICkgKTtcblxuXHRcdH1cblxuXHRcdHZhciBncm91cHMgPSBqc29uLmRhdGEuZ3JvdXBzIHx8IGpzb24uZGF0YS5kcmF3Y2FsbHMgfHwganNvbi5kYXRhLm9mZnNldHM7XG5cblx0XHRpZiAoIGdyb3VwcyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBncm91cHMubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHRcdHZhciBncm91cCA9IGdyb3Vwc1sgaSBdO1xuXG5cdFx0XHRcdGdlb21ldHJ5LmFkZEdyb3VwKCBncm91cC5zdGFydCwgZ3JvdXAuY291bnQsIGdyb3VwLm1hdGVyaWFsSW5kZXggKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dmFyIGJvdW5kaW5nU3BoZXJlID0ganNvbi5kYXRhLmJvdW5kaW5nU3BoZXJlO1xuXG5cdFx0aWYgKCBib3VuZGluZ1NwaGVyZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgY2VudGVyID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdFx0aWYgKCBib3VuZGluZ1NwaGVyZS5jZW50ZXIgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRjZW50ZXIuZnJvbUFycmF5KCBib3VuZGluZ1NwaGVyZS5jZW50ZXIgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRnZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSA9IG5ldyBTcGhlcmUoIGNlbnRlciwgYm91bmRpbmdTcGhlcmUucmFkaXVzICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gZ2VvbWV0cnk7XG5cblx0fVxuXG59ICk7XG5cbnZhciBUWVBFRF9BUlJBWVMgPSB7XG5cdEludDhBcnJheTogSW50OEFycmF5LFxuXHRVaW50OEFycmF5OiBVaW50OEFycmF5LFxuXHRVaW50OENsYW1wZWRBcnJheTogVWludDhDbGFtcGVkQXJyYXksXG5cdEludDE2QXJyYXk6IEludDE2QXJyYXksXG5cdFVpbnQxNkFycmF5OiBVaW50MTZBcnJheSxcblx0SW50MzJBcnJheTogSW50MzJBcnJheSxcblx0VWludDMyQXJyYXk6IFVpbnQzMkFycmF5LFxuXHRGbG9hdDMyQXJyYXk6IEZsb2F0MzJBcnJheSxcblx0RmxvYXQ2NEFycmF5OiBGbG9hdDY0QXJyYXlcbn07XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBMb2FkZXIoKSB7XG5cblx0dGhpcy5vbkxvYWRTdGFydCA9IGZ1bmN0aW9uICgpIHt9O1xuXHR0aGlzLm9uTG9hZFByb2dyZXNzID0gZnVuY3Rpb24gKCkge307XG5cdHRoaXMub25Mb2FkQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7fTtcblxufVxuXG5Mb2FkZXIuSGFuZGxlcnMgPSB7XG5cblx0aGFuZGxlcnM6IFtdLFxuXG5cdGFkZDogZnVuY3Rpb24gKCByZWdleCwgbG9hZGVyICkge1xuXG5cdFx0dGhpcy5oYW5kbGVycy5wdXNoKCByZWdleCwgbG9hZGVyICk7XG5cblx0fSxcblxuXHRnZXQ6IGZ1bmN0aW9uICggZmlsZSApIHtcblxuXHRcdHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnM7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBoYW5kbGVycy5sZW5ndGg7IGkgPCBsOyBpICs9IDIgKSB7XG5cblx0XHRcdHZhciByZWdleCA9IGhhbmRsZXJzWyBpIF07XG5cdFx0XHR2YXIgbG9hZGVyID0gaGFuZGxlcnNbIGkgKyAxIF07XG5cblx0XHRcdGlmICggcmVnZXgudGVzdCggZmlsZSApICkge1xuXG5cdFx0XHRcdHJldHVybiBsb2FkZXI7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiBudWxsO1xuXG5cdH1cblxufTtcblxuT2JqZWN0LmFzc2lnbiggTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGNyb3NzT3JpZ2luOiB1bmRlZmluZWQsXG5cblx0ZXh0cmFjdFVybEJhc2U6IGZ1bmN0aW9uICggdXJsICkge1xuXG5cdFx0dmFyIHBhcnRzID0gdXJsLnNwbGl0KCAnLycgKTtcblxuXHRcdGlmICggcGFydHMubGVuZ3RoID09PSAxICkgcmV0dXJuICcuLyc7XG5cblx0XHRwYXJ0cy5wb3AoKTtcblxuXHRcdHJldHVybiBwYXJ0cy5qb2luKCAnLycgKSArICcvJztcblxuXHR9LFxuXG5cdGluaXRNYXRlcmlhbHM6IGZ1bmN0aW9uICggbWF0ZXJpYWxzLCB0ZXh0dXJlUGF0aCwgY3Jvc3NPcmlnaW4gKSB7XG5cblx0XHR2YXIgYXJyYXkgPSBbXTtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IG1hdGVyaWFscy5sZW5ndGg7ICsrIGkgKSB7XG5cblx0XHRcdGFycmF5WyBpIF0gPSB0aGlzLmNyZWF0ZU1hdGVyaWFsKCBtYXRlcmlhbHNbIGkgXSwgdGV4dHVyZVBhdGgsIGNyb3NzT3JpZ2luICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyYXk7XG5cblx0fSxcblxuXHRjcmVhdGVNYXRlcmlhbDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgQmxlbmRpbmdNb2RlID0ge1xuXHRcdFx0Tm9CbGVuZGluZzogTm9CbGVuZGluZyxcblx0XHRcdE5vcm1hbEJsZW5kaW5nOiBOb3JtYWxCbGVuZGluZyxcblx0XHRcdEFkZGl0aXZlQmxlbmRpbmc6IEFkZGl0aXZlQmxlbmRpbmcsXG5cdFx0XHRTdWJ0cmFjdGl2ZUJsZW5kaW5nOiBTdWJ0cmFjdGl2ZUJsZW5kaW5nLFxuXHRcdFx0TXVsdGlwbHlCbGVuZGluZzogTXVsdGlwbHlCbGVuZGluZyxcblx0XHRcdEN1c3RvbUJsZW5kaW5nOiBDdXN0b21CbGVuZGluZ1xuXHRcdH07XG5cblx0XHR2YXIgY29sb3IgPSBuZXcgQ29sb3IoKTtcblx0XHR2YXIgdGV4dHVyZUxvYWRlciA9IG5ldyBUZXh0dXJlTG9hZGVyKCk7XG5cdFx0dmFyIG1hdGVyaWFsTG9hZGVyID0gbmV3IE1hdGVyaWFsTG9hZGVyKCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gY3JlYXRlTWF0ZXJpYWwoIG0sIHRleHR1cmVQYXRoLCBjcm9zc09yaWdpbiApIHtcblxuXHRcdFx0Ly8gY29udmVydCBmcm9tIG9sZCBtYXRlcmlhbCBmb3JtYXRcblxuXHRcdFx0dmFyIHRleHR1cmVzID0ge307XG5cblx0XHRcdGZ1bmN0aW9uIGxvYWRUZXh0dXJlKCBwYXRoLCByZXBlYXQsIG9mZnNldCwgd3JhcCwgYW5pc290cm9weSApIHtcblxuXHRcdFx0XHR2YXIgZnVsbFBhdGggPSB0ZXh0dXJlUGF0aCArIHBhdGg7XG5cdFx0XHRcdHZhciBsb2FkZXIgPSBMb2FkZXIuSGFuZGxlcnMuZ2V0KCBmdWxsUGF0aCApO1xuXG5cdFx0XHRcdHZhciB0ZXh0dXJlO1xuXG5cdFx0XHRcdGlmICggbG9hZGVyICE9PSBudWxsICkge1xuXG5cdFx0XHRcdFx0dGV4dHVyZSA9IGxvYWRlci5sb2FkKCBmdWxsUGF0aCApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHR0ZXh0dXJlTG9hZGVyLnNldENyb3NzT3JpZ2luKCBjcm9zc09yaWdpbiApO1xuXHRcdFx0XHRcdHRleHR1cmUgPSB0ZXh0dXJlTG9hZGVyLmxvYWQoIGZ1bGxQYXRoICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggcmVwZWF0ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHR0ZXh0dXJlLnJlcGVhdC5mcm9tQXJyYXkoIHJlcGVhdCApO1xuXG5cdFx0XHRcdFx0aWYgKCByZXBlYXRbIDAgXSAhPT0gMSApIHRleHR1cmUud3JhcFMgPSBSZXBlYXRXcmFwcGluZztcblx0XHRcdFx0XHRpZiAoIHJlcGVhdFsgMSBdICE9PSAxICkgdGV4dHVyZS53cmFwVCA9IFJlcGVhdFdyYXBwaW5nO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIG9mZnNldCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0dGV4dHVyZS5vZmZzZXQuZnJvbUFycmF5KCBvZmZzZXQgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCB3cmFwICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRpZiAoIHdyYXBbIDAgXSA9PT0gJ3JlcGVhdCcgKSB0ZXh0dXJlLndyYXBTID0gUmVwZWF0V3JhcHBpbmc7XG5cdFx0XHRcdFx0aWYgKCB3cmFwWyAwIF0gPT09ICdtaXJyb3InICkgdGV4dHVyZS53cmFwUyA9IE1pcnJvcmVkUmVwZWF0V3JhcHBpbmc7XG5cblx0XHRcdFx0XHRpZiAoIHdyYXBbIDEgXSA9PT0gJ3JlcGVhdCcgKSB0ZXh0dXJlLndyYXBUID0gUmVwZWF0V3JhcHBpbmc7XG5cdFx0XHRcdFx0aWYgKCB3cmFwWyAxIF0gPT09ICdtaXJyb3InICkgdGV4dHVyZS53cmFwVCA9IE1pcnJvcmVkUmVwZWF0V3JhcHBpbmc7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggYW5pc290cm9weSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0dGV4dHVyZS5hbmlzb3Ryb3B5ID0gYW5pc290cm9weTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dmFyIHV1aWQgPSBfTWF0aC5nZW5lcmF0ZVVVSUQoKTtcblxuXHRcdFx0XHR0ZXh0dXJlc1sgdXVpZCBdID0gdGV4dHVyZTtcblxuXHRcdFx0XHRyZXR1cm4gdXVpZDtcblxuXHRcdFx0fVxuXG5cdFx0XHQvL1xuXG5cdFx0XHR2YXIganNvbiA9IHtcblx0XHRcdFx0dXVpZDogX01hdGguZ2VuZXJhdGVVVUlEKCksXG5cdFx0XHRcdHR5cGU6ICdNZXNoTGFtYmVydE1hdGVyaWFsJ1xuXHRcdFx0fTtcblxuXHRcdFx0Zm9yICggdmFyIG5hbWUgaW4gbSApIHtcblxuXHRcdFx0XHR2YXIgdmFsdWUgPSBtWyBuYW1lIF07XG5cblx0XHRcdFx0c3dpdGNoICggbmFtZSApIHtcblxuXHRcdFx0XHRcdGNhc2UgJ0RiZ0NvbG9yJzpcblx0XHRcdFx0XHRjYXNlICdEYmdJbmRleCc6XG5cdFx0XHRcdFx0Y2FzZSAnb3B0aWNhbERlbnNpdHknOlxuXHRcdFx0XHRcdGNhc2UgJ2lsbHVtaW5hdGlvbic6XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdEYmdOYW1lJzpcblx0XHRcdFx0XHRcdGpzb24ubmFtZSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnYmxlbmRpbmcnOlxuXHRcdFx0XHRcdFx0anNvbi5ibGVuZGluZyA9IEJsZW5kaW5nTW9kZVsgdmFsdWUgXTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ2NvbG9yQW1iaWVudCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQW1iaWVudCc6XG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Mb2FkZXIuY3JlYXRlTWF0ZXJpYWw6JywgbmFtZSwgJ2lzIG5vIGxvbmdlciBzdXBwb3J0ZWQuJyApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnY29sb3JEaWZmdXNlJzpcblx0XHRcdFx0XHRcdGpzb24uY29sb3IgPSBjb2xvci5mcm9tQXJyYXkoIHZhbHVlICkuZ2V0SGV4KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdjb2xvclNwZWN1bGFyJzpcblx0XHRcdFx0XHRcdGpzb24uc3BlY3VsYXIgPSBjb2xvci5mcm9tQXJyYXkoIHZhbHVlICkuZ2V0SGV4KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdjb2xvckVtaXNzaXZlJzpcblx0XHRcdFx0XHRcdGpzb24uZW1pc3NpdmUgPSBjb2xvci5mcm9tQXJyYXkoIHZhbHVlICkuZ2V0SGV4KCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdzcGVjdWxhckNvZWYnOlxuXHRcdFx0XHRcdFx0anNvbi5zaGluaW5lc3MgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ3NoYWRpbmcnOlxuXHRcdFx0XHRcdFx0aWYgKCB2YWx1ZS50b0xvd2VyQ2FzZSgpID09PSAnYmFzaWMnICkganNvbi50eXBlID0gJ01lc2hCYXNpY01hdGVyaWFsJztcblx0XHRcdFx0XHRcdGlmICggdmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gJ3Bob25nJyApIGpzb24udHlwZSA9ICdNZXNoUGhvbmdNYXRlcmlhbCc7XG5cdFx0XHRcdFx0XHRpZiAoIHZhbHVlLnRvTG93ZXJDYXNlKCkgPT09ICdzdGFuZGFyZCcgKSBqc29uLnR5cGUgPSAnTWVzaFN0YW5kYXJkTWF0ZXJpYWwnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwRGlmZnVzZSc6XG5cdFx0XHRcdFx0XHRqc29uLm1hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBEaWZmdXNlUmVwZWF0LCBtLm1hcERpZmZ1c2VPZmZzZXQsIG0ubWFwRGlmZnVzZVdyYXAsIG0ubWFwRGlmZnVzZUFuaXNvdHJvcHkgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcERpZmZ1c2VSZXBlYXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcERpZmZ1c2VPZmZzZXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcERpZmZ1c2VXcmFwJzpcblx0XHRcdFx0XHRjYXNlICdtYXBEaWZmdXNlQW5pc290cm9weSc6XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBFbWlzc2l2ZSc6XG5cdFx0XHRcdFx0XHRqc29uLmVtaXNzaXZlTWFwID0gbG9hZFRleHR1cmUoIHZhbHVlLCBtLm1hcEVtaXNzaXZlUmVwZWF0LCBtLm1hcEVtaXNzaXZlT2Zmc2V0LCBtLm1hcEVtaXNzaXZlV3JhcCwgbS5tYXBFbWlzc2l2ZUFuaXNvdHJvcHkgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcEVtaXNzaXZlUmVwZWF0Jzpcblx0XHRcdFx0XHRjYXNlICdtYXBFbWlzc2l2ZU9mZnNldCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwRW1pc3NpdmVXcmFwJzpcblx0XHRcdFx0XHRjYXNlICdtYXBFbWlzc2l2ZUFuaXNvdHJvcHknOlxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTGlnaHQnOlxuXHRcdFx0XHRcdFx0anNvbi5saWdodE1hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBMaWdodFJlcGVhdCwgbS5tYXBMaWdodE9mZnNldCwgbS5tYXBMaWdodFdyYXAsIG0ubWFwTGlnaHRBbmlzb3Ryb3B5ICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBMaWdodFJlcGVhdCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTGlnaHRPZmZzZXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcExpZ2h0V3JhcCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTGlnaHRBbmlzb3Ryb3B5Jzpcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcEFPJzpcblx0XHRcdFx0XHRcdGpzb24uYW9NYXAgPSBsb2FkVGV4dHVyZSggdmFsdWUsIG0ubWFwQU9SZXBlYXQsIG0ubWFwQU9PZmZzZXQsIG0ubWFwQU9XcmFwLCBtLm1hcEFPQW5pc290cm9weSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQU9SZXBlYXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcEFPT2Zmc2V0Jzpcblx0XHRcdFx0XHRjYXNlICdtYXBBT1dyYXAnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcEFPQW5pc290cm9weSc6XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBCdW1wJzpcblx0XHRcdFx0XHRcdGpzb24uYnVtcE1hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBCdW1wUmVwZWF0LCBtLm1hcEJ1bXBPZmZzZXQsIG0ubWFwQnVtcFdyYXAsIG0ubWFwQnVtcEFuaXNvdHJvcHkgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcEJ1bXBTY2FsZSc6XG5cdFx0XHRcdFx0XHRqc29uLmJ1bXBTY2FsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQnVtcFJlcGVhdCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQnVtcE9mZnNldCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQnVtcFdyYXAnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcEJ1bXBBbmlzb3Ryb3B5Jzpcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcE5vcm1hbCc6XG5cdFx0XHRcdFx0XHRqc29uLm5vcm1hbE1hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBOb3JtYWxSZXBlYXQsIG0ubWFwTm9ybWFsT2Zmc2V0LCBtLm1hcE5vcm1hbFdyYXAsIG0ubWFwTm9ybWFsQW5pc290cm9weSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTm9ybWFsRmFjdG9yJzpcblx0XHRcdFx0XHRcdGpzb24ubm9ybWFsU2NhbGUgPSBbIHZhbHVlLCB2YWx1ZSBdO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTm9ybWFsUmVwZWF0Jzpcblx0XHRcdFx0XHRjYXNlICdtYXBOb3JtYWxPZmZzZXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcE5vcm1hbFdyYXAnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcE5vcm1hbEFuaXNvdHJvcHknOlxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwU3BlY3VsYXInOlxuXHRcdFx0XHRcdFx0anNvbi5zcGVjdWxhck1hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBTcGVjdWxhclJlcGVhdCwgbS5tYXBTcGVjdWxhck9mZnNldCwgbS5tYXBTcGVjdWxhcldyYXAsIG0ubWFwU3BlY3VsYXJBbmlzb3Ryb3B5ICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBTcGVjdWxhclJlcGVhdCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwU3BlY3VsYXJPZmZzZXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcFNwZWN1bGFyV3JhcCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwU3BlY3VsYXJBbmlzb3Ryb3B5Jzpcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcE1ldGFsbmVzcyc6XG5cdFx0XHRcdFx0XHRqc29uLm1ldGFsbmVzc01hcCA9IGxvYWRUZXh0dXJlKCB2YWx1ZSwgbS5tYXBNZXRhbG5lc3NSZXBlYXQsIG0ubWFwTWV0YWxuZXNzT2Zmc2V0LCBtLm1hcE1ldGFsbmVzc1dyYXAsIG0ubWFwTWV0YWxuZXNzQW5pc290cm9weSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwTWV0YWxuZXNzUmVwZWF0Jzpcblx0XHRcdFx0XHRjYXNlICdtYXBNZXRhbG5lc3NPZmZzZXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcE1ldGFsbmVzc1dyYXAnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcE1ldGFsbmVzc0FuaXNvdHJvcHknOlxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWFwUm91Z2huZXNzJzpcblx0XHRcdFx0XHRcdGpzb24ucm91Z2huZXNzTWFwID0gbG9hZFRleHR1cmUoIHZhbHVlLCBtLm1hcFJvdWdobmVzc1JlcGVhdCwgbS5tYXBSb3VnaG5lc3NPZmZzZXQsIG0ubWFwUm91Z2huZXNzV3JhcCwgbS5tYXBSb3VnaG5lc3NBbmlzb3Ryb3B5ICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBSb3VnaG5lc3NSZXBlYXQnOlxuXHRcdFx0XHRcdGNhc2UgJ21hcFJvdWdobmVzc09mZnNldCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwUm91Z2huZXNzV3JhcCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwUm91Z2huZXNzQW5pc290cm9weSc6XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtYXBBbHBoYSc6XG5cdFx0XHRcdFx0XHRqc29uLmFscGhhTWFwID0gbG9hZFRleHR1cmUoIHZhbHVlLCBtLm1hcEFscGhhUmVwZWF0LCBtLm1hcEFscGhhT2Zmc2V0LCBtLm1hcEFscGhhV3JhcCwgbS5tYXBBbHBoYUFuaXNvdHJvcHkgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ21hcEFscGhhUmVwZWF0Jzpcblx0XHRcdFx0XHRjYXNlICdtYXBBbHBoYU9mZnNldCc6XG5cdFx0XHRcdFx0Y2FzZSAnbWFwQWxwaGFXcmFwJzpcblx0XHRcdFx0XHRjYXNlICdtYXBBbHBoYUFuaXNvdHJvcHknOlxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnZmxpcFNpZGVkJzpcblx0XHRcdFx0XHRcdGpzb24uc2lkZSA9IEJhY2tTaWRlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnZG91YmxlU2lkZWQnOlxuXHRcdFx0XHRcdFx0anNvbi5zaWRlID0gRG91YmxlU2lkZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ3RyYW5zcGFyZW5jeSc6XG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Mb2FkZXIuY3JlYXRlTWF0ZXJpYWw6IHRyYW5zcGFyZW5jeSBoYXMgYmVlbiByZW5hbWVkIHRvIG9wYWNpdHknICk7XG5cdFx0XHRcdFx0XHRqc29uLm9wYWNpdHkgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ2RlcHRoVGVzdCc6XG5cdFx0XHRcdFx0Y2FzZSAnZGVwdGhXcml0ZSc6XG5cdFx0XHRcdFx0Y2FzZSAnY29sb3JXcml0ZSc6XG5cdFx0XHRcdFx0Y2FzZSAnb3BhY2l0eSc6XG5cdFx0XHRcdFx0Y2FzZSAncmVmbGVjdGl2aXR5Jzpcblx0XHRcdFx0XHRjYXNlICd0cmFuc3BhcmVudCc6XG5cdFx0XHRcdFx0Y2FzZSAndmlzaWJsZSc6XG5cdFx0XHRcdFx0Y2FzZSAnd2lyZWZyYW1lJzpcblx0XHRcdFx0XHRcdGpzb25bIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAndmVydGV4Q29sb3JzJzpcblx0XHRcdFx0XHRcdGlmICggdmFsdWUgPT09IHRydWUgKSBqc29uLnZlcnRleENvbG9ycyA9IFZlcnRleENvbG9ycztcblx0XHRcdFx0XHRcdGlmICggdmFsdWUgPT09ICdmYWNlJyApIGpzb24udmVydGV4Q29sb3JzID0gRmFjZUNvbG9ycztcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuTG9hZGVyLmNyZWF0ZU1hdGVyaWFsOiBVbnN1cHBvcnRlZCcsIG5hbWUsIHZhbHVlICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBqc29uLnR5cGUgPT09ICdNZXNoQmFzaWNNYXRlcmlhbCcgKSBkZWxldGUganNvbi5lbWlzc2l2ZTtcblx0XHRcdGlmICgganNvbi50eXBlICE9PSAnTWVzaFBob25nTWF0ZXJpYWwnICkgZGVsZXRlIGpzb24uc3BlY3VsYXI7XG5cblx0XHRcdGlmICgganNvbi5vcGFjaXR5IDwgMSApIGpzb24udHJhbnNwYXJlbnQgPSB0cnVlO1xuXG5cdFx0XHRtYXRlcmlhbExvYWRlci5zZXRUZXh0dXJlcyggdGV4dHVyZXMgKTtcblxuXHRcdFx0cmV0dXJuIG1hdGVyaWFsTG9hZGVyLnBhcnNlKCBqc29uICk7XG5cblx0XHR9O1xuXG5cdH0gKSgpXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBKU09OTG9hZGVyKCBtYW5hZ2VyICkge1xuXG5cdGlmICggdHlwZW9mIG1hbmFnZXIgPT09ICdib29sZWFuJyApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkpTT05Mb2FkZXI6IHNob3dTdGF0dXMgcGFyYW1ldGVyIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSBjb25zdHJ1Y3Rvci4nICk7XG5cdFx0bWFuYWdlciA9IHVuZGVmaW5lZDtcblxuXHR9XG5cblx0dGhpcy5tYW5hZ2VyID0gKCBtYW5hZ2VyICE9PSB1bmRlZmluZWQgKSA/IG1hbmFnZXIgOiBEZWZhdWx0TG9hZGluZ01hbmFnZXI7XG5cblx0dGhpcy53aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBKU09OTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIHRleHR1cmVQYXRoID0gdGhpcy50ZXh0dXJlUGF0aCAmJiAoIHR5cGVvZiB0aGlzLnRleHR1cmVQYXRoID09PSBcInN0cmluZ1wiICkgPyB0aGlzLnRleHR1cmVQYXRoIDogTG9hZGVyLnByb3RvdHlwZS5leHRyYWN0VXJsQmFzZSggdXJsICk7XG5cblx0XHR2YXIgbG9hZGVyID0gbmV3IEZpbGVMb2FkZXIoIHRoaXMubWFuYWdlciApO1xuXHRcdGxvYWRlci5zZXRSZXNwb25zZVR5cGUoICdqc29uJyApO1xuXHRcdGxvYWRlci5zZXRXaXRoQ3JlZGVudGlhbHMoIHRoaXMud2l0aENyZWRlbnRpYWxzICk7XG5cdFx0bG9hZGVyLmxvYWQoIHVybCwgZnVuY3Rpb24gKCBqc29uICkge1xuXG5cdFx0XHR2YXIgbWV0YWRhdGEgPSBqc29uLm1ldGFkYXRhO1xuXG5cdFx0XHRpZiAoIG1ldGFkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0dmFyIHR5cGUgPSBtZXRhZGF0YS50eXBlO1xuXG5cdFx0XHRcdGlmICggdHlwZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdFx0aWYgKCB0eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdvYmplY3QnICkge1xuXG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuSlNPTkxvYWRlcjogJyArIHVybCArICcgc2hvdWxkIGJlIGxvYWRlZCB3aXRoIFRIUkVFLk9iamVjdExvYWRlciBpbnN0ZWFkLicgKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggdHlwZS50b0xvd2VyQ2FzZSgpID09PSAnc2NlbmUnICkge1xuXG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuSlNPTkxvYWRlcjogJyArIHVybCArICcgc2hvdWxkIGJlIGxvYWRlZCB3aXRoIFRIUkVFLlNjZW5lTG9hZGVyIGluc3RlYWQuJyApO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgb2JqZWN0ID0gc2NvcGUucGFyc2UoIGpzb24sIHRleHR1cmVQYXRoICk7XG5cdFx0XHRvbkxvYWQoIG9iamVjdC5nZW9tZXRyeSwgb2JqZWN0Lm1hdGVyaWFscyApO1xuXG5cdFx0fSwgb25Qcm9ncmVzcywgb25FcnJvciApO1xuXG5cdH0sXG5cblx0c2V0VGV4dHVyZVBhdGg6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLnRleHR1cmVQYXRoID0gdmFsdWU7XG5cblx0fSxcblxuXHRwYXJzZTogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHRmdW5jdGlvbiBwYXJzZU1vZGVsKCBqc29uLCBnZW9tZXRyeSApIHtcblxuXHRcdFx0ZnVuY3Rpb24gaXNCaXRTZXQoIHZhbHVlLCBwb3NpdGlvbiApIHtcblxuXHRcdFx0XHRyZXR1cm4gdmFsdWUgJiAoIDEgPDwgcG9zaXRpb24gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgaSwgaiwgZmksXG5cblx0XHRcdFx0b2Zmc2V0LCB6TGVuZ3RoLFxuXG5cdFx0XHRcdGNvbG9ySW5kZXgsIG5vcm1hbEluZGV4LCB1dkluZGV4LCBtYXRlcmlhbEluZGV4LFxuXG5cdFx0XHRcdHR5cGUsXG5cdFx0XHRcdGlzUXVhZCxcblx0XHRcdFx0aGFzTWF0ZXJpYWwsXG5cdFx0XHRcdGhhc0ZhY2VWZXJ0ZXhVdixcblx0XHRcdFx0aGFzRmFjZU5vcm1hbCwgaGFzRmFjZVZlcnRleE5vcm1hbCxcblx0XHRcdFx0aGFzRmFjZUNvbG9yLCBoYXNGYWNlVmVydGV4Q29sb3IsXG5cblx0XHRcdFx0dmVydGV4LCBmYWNlLCBmYWNlQSwgZmFjZUIsIGhleCwgbm9ybWFsLFxuXG5cdFx0XHRcdHV2TGF5ZXIsIHV2LCB1LCB2LFxuXG5cdFx0XHRcdGZhY2VzID0ganNvbi5mYWNlcyxcblx0XHRcdFx0dmVydGljZXMgPSBqc29uLnZlcnRpY2VzLFxuXHRcdFx0XHRub3JtYWxzID0ganNvbi5ub3JtYWxzLFxuXHRcdFx0XHRjb2xvcnMgPSBqc29uLmNvbG9ycyxcblxuXHRcdFx0XHRzY2FsZSA9IGpzb24uc2NhbGUsXG5cblx0XHRcdFx0blV2TGF5ZXJzID0gMDtcblxuXG5cdFx0XHRpZiAoIGpzb24udXZzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gZGlzcmVnYXJkIGVtcHR5IGFycmF5c1xuXG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwganNvbi51dnMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCBqc29uLnV2c1sgaSBdLmxlbmd0aCApIG5VdkxheWVycyArKztcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBuVXZMYXllcnM7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRnZW9tZXRyeS5mYWNlVmVydGV4VXZzWyBpIF0gPSBbXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0b2Zmc2V0ID0gMDtcblx0XHRcdHpMZW5ndGggPSB2ZXJ0aWNlcy5sZW5ndGg7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0IDwgekxlbmd0aCApIHtcblxuXHRcdFx0XHR2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0XHRcdHZlcnRleC54ID0gdmVydGljZXNbIG9mZnNldCArKyBdICogc2NhbGU7XG5cdFx0XHRcdHZlcnRleC55ID0gdmVydGljZXNbIG9mZnNldCArKyBdICogc2NhbGU7XG5cdFx0XHRcdHZlcnRleC56ID0gdmVydGljZXNbIG9mZnNldCArKyBdICogc2NhbGU7XG5cblx0XHRcdFx0Z2VvbWV0cnkudmVydGljZXMucHVzaCggdmVydGV4ICk7XG5cblx0XHRcdH1cblxuXHRcdFx0b2Zmc2V0ID0gMDtcblx0XHRcdHpMZW5ndGggPSBmYWNlcy5sZW5ndGg7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0IDwgekxlbmd0aCApIHtcblxuXHRcdFx0XHR0eXBlID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXG5cdFx0XHRcdGlzUXVhZCA9IGlzQml0U2V0KCB0eXBlLCAwICk7XG5cdFx0XHRcdGhhc01hdGVyaWFsID0gaXNCaXRTZXQoIHR5cGUsIDEgKTtcblx0XHRcdFx0aGFzRmFjZVZlcnRleFV2ID0gaXNCaXRTZXQoIHR5cGUsIDMgKTtcblx0XHRcdFx0aGFzRmFjZU5vcm1hbCA9IGlzQml0U2V0KCB0eXBlLCA0ICk7XG5cdFx0XHRcdGhhc0ZhY2VWZXJ0ZXhOb3JtYWwgPSBpc0JpdFNldCggdHlwZSwgNSApO1xuXHRcdFx0XHRoYXNGYWNlQ29sb3IgPSBpc0JpdFNldCggdHlwZSwgNiApO1xuXHRcdFx0XHRoYXNGYWNlVmVydGV4Q29sb3IgPSBpc0JpdFNldCggdHlwZSwgNyApO1xuXG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKFwidHlwZVwiLCB0eXBlLCBcImJpdHNcIiwgaXNRdWFkLCBoYXNNYXRlcmlhbCwgaGFzRmFjZVZlcnRleFV2LCBoYXNGYWNlTm9ybWFsLCBoYXNGYWNlVmVydGV4Tm9ybWFsLCBoYXNGYWNlQ29sb3IsIGhhc0ZhY2VWZXJ0ZXhDb2xvcik7XG5cblx0XHRcdFx0aWYgKCBpc1F1YWQgKSB7XG5cblx0XHRcdFx0XHRmYWNlQSA9IG5ldyBGYWNlMygpO1xuXHRcdFx0XHRcdGZhY2VBLmEgPSBmYWNlc1sgb2Zmc2V0IF07XG5cdFx0XHRcdFx0ZmFjZUEuYiA9IGZhY2VzWyBvZmZzZXQgKyAxIF07XG5cdFx0XHRcdFx0ZmFjZUEuYyA9IGZhY2VzWyBvZmZzZXQgKyAzIF07XG5cblx0XHRcdFx0XHRmYWNlQiA9IG5ldyBGYWNlMygpO1xuXHRcdFx0XHRcdGZhY2VCLmEgPSBmYWNlc1sgb2Zmc2V0ICsgMSBdO1xuXHRcdFx0XHRcdGZhY2VCLmIgPSBmYWNlc1sgb2Zmc2V0ICsgMiBdO1xuXHRcdFx0XHRcdGZhY2VCLmMgPSBmYWNlc1sgb2Zmc2V0ICsgMyBdO1xuXG5cdFx0XHRcdFx0b2Zmc2V0ICs9IDQ7XG5cblx0XHRcdFx0XHRpZiAoIGhhc01hdGVyaWFsICkge1xuXG5cdFx0XHRcdFx0XHRtYXRlcmlhbEluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXHRcdFx0XHRcdFx0ZmFjZUEubWF0ZXJpYWxJbmRleCA9IG1hdGVyaWFsSW5kZXg7XG5cdFx0XHRcdFx0XHRmYWNlQi5tYXRlcmlhbEluZGV4ID0gbWF0ZXJpYWxJbmRleDtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIHRvIGdldCBmYWNlIDw9PiB1diBpbmRleCBjb3JyZXNwb25kZW5jZVxuXG5cdFx0XHRcdFx0ZmkgPSBnZW9tZXRyeS5mYWNlcy5sZW5ndGg7XG5cblx0XHRcdFx0XHRpZiAoIGhhc0ZhY2VWZXJ0ZXhVdiApIHtcblxuXHRcdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBuVXZMYXllcnM7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0dXZMYXllciA9IGpzb24udXZzWyBpIF07XG5cblx0XHRcdFx0XHRcdFx0Z2VvbWV0cnkuZmFjZVZlcnRleFV2c1sgaSBdWyBmaSBdID0gW107XG5cdFx0XHRcdFx0XHRcdGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbIGkgXVsgZmkgKyAxIF0gPSBbXTtcblxuXHRcdFx0XHRcdFx0XHRmb3IgKCBqID0gMDsgaiA8IDQ7IGogKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHR1dkluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0dSA9IHV2TGF5ZXJbIHV2SW5kZXggKiAyIF07XG5cdFx0XHRcdFx0XHRcdFx0diA9IHV2TGF5ZXJbIHV2SW5kZXggKiAyICsgMSBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0dXYgPSBuZXcgVmVjdG9yMiggdSwgdiApO1xuXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBqICE9PSAyICkgZ2VvbWV0cnkuZmFjZVZlcnRleFV2c1sgaSBdWyBmaSBdLnB1c2goIHV2ICk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBqICE9PSAwICkgZ2VvbWV0cnkuZmFjZVZlcnRleFV2c1sgaSBdWyBmaSArIDEgXS5wdXNoKCB1diApO1xuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCBoYXNGYWNlTm9ybWFsICkge1xuXG5cdFx0XHRcdFx0XHRub3JtYWxJbmRleCA9IGZhY2VzWyBvZmZzZXQgKysgXSAqIDM7XG5cblx0XHRcdFx0XHRcdGZhY2VBLm5vcm1hbC5zZXQoXG5cdFx0XHRcdFx0XHRcdG5vcm1hbHNbIG5vcm1hbEluZGV4ICsrIF0sXG5cdFx0XHRcdFx0XHRcdG5vcm1hbHNbIG5vcm1hbEluZGV4ICsrIF0sXG5cdFx0XHRcdFx0XHRcdG5vcm1hbHNbIG5vcm1hbEluZGV4IF1cblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdGZhY2VCLm5vcm1hbC5jb3B5KCBmYWNlQS5ub3JtYWwgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggaGFzRmFjZVZlcnRleE5vcm1hbCApIHtcblxuXHRcdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCA0OyBpICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdG5vcm1hbEluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdICogMztcblxuXHRcdFx0XHRcdFx0XHRub3JtYWwgPSBuZXcgVmVjdG9yMyhcblx0XHRcdFx0XHRcdFx0XHRub3JtYWxzWyBub3JtYWxJbmRleCArKyBdLFxuXHRcdFx0XHRcdFx0XHRcdG5vcm1hbHNbIG5vcm1hbEluZGV4ICsrIF0sXG5cdFx0XHRcdFx0XHRcdFx0bm9ybWFsc1sgbm9ybWFsSW5kZXggXVxuXHRcdFx0XHRcdFx0XHQpO1xuXG5cblx0XHRcdFx0XHRcdFx0aWYgKCBpICE9PSAyICkgZmFjZUEudmVydGV4Tm9ybWFscy5wdXNoKCBub3JtYWwgKTtcblx0XHRcdFx0XHRcdFx0aWYgKCBpICE9PSAwICkgZmFjZUIudmVydGV4Tm9ybWFscy5wdXNoKCBub3JtYWwgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cblx0XHRcdFx0XHRpZiAoIGhhc0ZhY2VDb2xvciApIHtcblxuXHRcdFx0XHRcdFx0Y29sb3JJbmRleCA9IGZhY2VzWyBvZmZzZXQgKysgXTtcblx0XHRcdFx0XHRcdGhleCA9IGNvbG9yc1sgY29sb3JJbmRleCBdO1xuXG5cdFx0XHRcdFx0XHRmYWNlQS5jb2xvci5zZXRIZXgoIGhleCApO1xuXHRcdFx0XHRcdFx0ZmFjZUIuY29sb3Iuc2V0SGV4KCBoZXggKTtcblxuXHRcdFx0XHRcdH1cblxuXG5cdFx0XHRcdFx0aWYgKCBoYXNGYWNlVmVydGV4Q29sb3IgKSB7XG5cblx0XHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgNDsgaSArKyApIHtcblxuXHRcdFx0XHRcdFx0XHRjb2xvckluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXHRcdFx0XHRcdFx0XHRoZXggPSBjb2xvcnNbIGNvbG9ySW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIGkgIT09IDIgKSBmYWNlQS52ZXJ0ZXhDb2xvcnMucHVzaCggbmV3IENvbG9yKCBoZXggKSApO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGkgIT09IDAgKSBmYWNlQi52ZXJ0ZXhDb2xvcnMucHVzaCggbmV3IENvbG9yKCBoZXggKSApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRnZW9tZXRyeS5mYWNlcy5wdXNoKCBmYWNlQSApO1xuXHRcdFx0XHRcdGdlb21ldHJ5LmZhY2VzLnB1c2goIGZhY2VCICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGZhY2UgPSBuZXcgRmFjZTMoKTtcblx0XHRcdFx0XHRmYWNlLmEgPSBmYWNlc1sgb2Zmc2V0ICsrIF07XG5cdFx0XHRcdFx0ZmFjZS5iID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXHRcdFx0XHRcdGZhY2UuYyA9IGZhY2VzWyBvZmZzZXQgKysgXTtcblxuXHRcdFx0XHRcdGlmICggaGFzTWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0XHRcdG1hdGVyaWFsSW5kZXggPSBmYWNlc1sgb2Zmc2V0ICsrIF07XG5cdFx0XHRcdFx0XHRmYWNlLm1hdGVyaWFsSW5kZXggPSBtYXRlcmlhbEluZGV4O1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gdG8gZ2V0IGZhY2UgPD0+IHV2IGluZGV4IGNvcnJlc3BvbmRlbmNlXG5cblx0XHRcdFx0XHRmaSA9IGdlb21ldHJ5LmZhY2VzLmxlbmd0aDtcblxuXHRcdFx0XHRcdGlmICggaGFzRmFjZVZlcnRleFV2ICkge1xuXG5cdFx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IG5VdkxheWVyczsgaSArKyApIHtcblxuXHRcdFx0XHRcdFx0XHR1dkxheWVyID0ganNvbi51dnNbIGkgXTtcblxuXHRcdFx0XHRcdFx0XHRnZW9tZXRyeS5mYWNlVmVydGV4VXZzWyBpIF1bIGZpIF0gPSBbXTtcblxuXHRcdFx0XHRcdFx0XHRmb3IgKCBqID0gMDsgaiA8IDM7IGogKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHR1dkluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0dSA9IHV2TGF5ZXJbIHV2SW5kZXggKiAyIF07XG5cdFx0XHRcdFx0XHRcdFx0diA9IHV2TGF5ZXJbIHV2SW5kZXggKiAyICsgMSBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0dXYgPSBuZXcgVmVjdG9yMiggdSwgdiApO1xuXG5cdFx0XHRcdFx0XHRcdFx0Z2VvbWV0cnkuZmFjZVZlcnRleFV2c1sgaSBdWyBmaSBdLnB1c2goIHV2ICk7XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGhhc0ZhY2VOb3JtYWwgKSB7XG5cblx0XHRcdFx0XHRcdG5vcm1hbEluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdICogMztcblxuXHRcdFx0XHRcdFx0ZmFjZS5ub3JtYWwuc2V0KFxuXHRcdFx0XHRcdFx0XHRub3JtYWxzWyBub3JtYWxJbmRleCArKyBdLFxuXHRcdFx0XHRcdFx0XHRub3JtYWxzWyBub3JtYWxJbmRleCArKyBdLFxuXHRcdFx0XHRcdFx0XHRub3JtYWxzWyBub3JtYWxJbmRleCBdXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCBoYXNGYWNlVmVydGV4Tm9ybWFsICkge1xuXG5cdFx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IDM7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0bm9ybWFsSW5kZXggPSBmYWNlc1sgb2Zmc2V0ICsrIF0gKiAzO1xuXG5cdFx0XHRcdFx0XHRcdG5vcm1hbCA9IG5ldyBWZWN0b3IzKFxuXHRcdFx0XHRcdFx0XHRcdG5vcm1hbHNbIG5vcm1hbEluZGV4ICsrIF0sXG5cdFx0XHRcdFx0XHRcdFx0bm9ybWFsc1sgbm9ybWFsSW5kZXggKysgXSxcblx0XHRcdFx0XHRcdFx0XHRub3JtYWxzWyBub3JtYWxJbmRleCBdXG5cdFx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdFx0ZmFjZS52ZXJ0ZXhOb3JtYWxzLnB1c2goIG5vcm1hbCApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblxuXHRcdFx0XHRcdGlmICggaGFzRmFjZUNvbG9yICkge1xuXG5cdFx0XHRcdFx0XHRjb2xvckluZGV4ID0gZmFjZXNbIG9mZnNldCArKyBdO1xuXHRcdFx0XHRcdFx0ZmFjZS5jb2xvci5zZXRIZXgoIGNvbG9yc1sgY29sb3JJbmRleCBdICk7XG5cblx0XHRcdFx0XHR9XG5cblxuXHRcdFx0XHRcdGlmICggaGFzRmFjZVZlcnRleENvbG9yICkge1xuXG5cdFx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IDM7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0Y29sb3JJbmRleCA9IGZhY2VzWyBvZmZzZXQgKysgXTtcblx0XHRcdFx0XHRcdFx0ZmFjZS52ZXJ0ZXhDb2xvcnMucHVzaCggbmV3IENvbG9yKCBjb2xvcnNbIGNvbG9ySW5kZXggXSApICk7XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGdlb21ldHJ5LmZhY2VzLnB1c2goIGZhY2UgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHBhcnNlU2tpbigganNvbiwgZ2VvbWV0cnkgKSB7XG5cblx0XHRcdHZhciBpbmZsdWVuY2VzUGVyVmVydGV4ID0gKCBqc29uLmluZmx1ZW5jZXNQZXJWZXJ0ZXggIT09IHVuZGVmaW5lZCApID8ganNvbi5pbmZsdWVuY2VzUGVyVmVydGV4IDogMjtcblxuXHRcdFx0aWYgKCBqc29uLnNraW5XZWlnaHRzICkge1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGpzb24uc2tpbldlaWdodHMubGVuZ3RoOyBpIDwgbDsgaSArPSBpbmZsdWVuY2VzUGVyVmVydGV4ICkge1xuXG5cdFx0XHRcdFx0dmFyIHggPSBqc29uLnNraW5XZWlnaHRzWyBpIF07XG5cdFx0XHRcdFx0dmFyIHkgPSAoIGluZmx1ZW5jZXNQZXJWZXJ0ZXggPiAxICkgPyBqc29uLnNraW5XZWlnaHRzWyBpICsgMSBdIDogMDtcblx0XHRcdFx0XHR2YXIgeiA9ICggaW5mbHVlbmNlc1BlclZlcnRleCA+IDIgKSA/IGpzb24uc2tpbldlaWdodHNbIGkgKyAyIF0gOiAwO1xuXHRcdFx0XHRcdHZhciB3ID0gKCBpbmZsdWVuY2VzUGVyVmVydGV4ID4gMyApID8ganNvbi5za2luV2VpZ2h0c1sgaSArIDMgXSA6IDA7XG5cblx0XHRcdFx0XHRnZW9tZXRyeS5za2luV2VpZ2h0cy5wdXNoKCBuZXcgVmVjdG9yNCggeCwgeSwgeiwgdyApICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdGlmICgganNvbi5za2luSW5kaWNlcyApIHtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBqc29uLnNraW5JbmRpY2VzLmxlbmd0aDsgaSA8IGw7IGkgKz0gaW5mbHVlbmNlc1BlclZlcnRleCApIHtcblxuXHRcdFx0XHRcdHZhciBhID0ganNvbi5za2luSW5kaWNlc1sgaSBdO1xuXHRcdFx0XHRcdHZhciBiID0gKCBpbmZsdWVuY2VzUGVyVmVydGV4ID4gMSApID8ganNvbi5za2luSW5kaWNlc1sgaSArIDEgXSA6IDA7XG5cdFx0XHRcdFx0dmFyIGMgPSAoIGluZmx1ZW5jZXNQZXJWZXJ0ZXggPiAyICkgPyBqc29uLnNraW5JbmRpY2VzWyBpICsgMiBdIDogMDtcblx0XHRcdFx0XHR2YXIgZCA9ICggaW5mbHVlbmNlc1BlclZlcnRleCA+IDMgKSA/IGpzb24uc2tpbkluZGljZXNbIGkgKyAzIF0gOiAwO1xuXG5cdFx0XHRcdFx0Z2VvbWV0cnkuc2tpbkluZGljZXMucHVzaCggbmV3IFZlY3RvcjQoIGEsIGIsIGMsIGQgKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRnZW9tZXRyeS5ib25lcyA9IGpzb24uYm9uZXM7XG5cblx0XHRcdGlmICggZ2VvbWV0cnkuYm9uZXMgJiYgZ2VvbWV0cnkuYm9uZXMubGVuZ3RoID4gMCAmJiAoIGdlb21ldHJ5LnNraW5XZWlnaHRzLmxlbmd0aCAhPT0gZ2VvbWV0cnkuc2tpbkluZGljZXMubGVuZ3RoIHx8IGdlb21ldHJ5LnNraW5JbmRpY2VzLmxlbmd0aCAhPT0gZ2VvbWV0cnkudmVydGljZXMubGVuZ3RoICkgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnV2hlbiBza2lubmluZywgbnVtYmVyIG9mIHZlcnRpY2VzICgnICsgZ2VvbWV0cnkudmVydGljZXMubGVuZ3RoICsgJyksIHNraW5JbmRpY2VzICgnICtcblx0XHRcdFx0XHRnZW9tZXRyeS5za2luSW5kaWNlcy5sZW5ndGggKyAnKSwgYW5kIHNraW5XZWlnaHRzICgnICsgZ2VvbWV0cnkuc2tpbldlaWdodHMubGVuZ3RoICsgJykgc2hvdWxkIG1hdGNoLicgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gcGFyc2VNb3JwaGluZygganNvbiwgZ2VvbWV0cnkgKSB7XG5cblx0XHRcdHZhciBzY2FsZSA9IGpzb24uc2NhbGU7XG5cblx0XHRcdGlmICgganNvbi5tb3JwaFRhcmdldHMgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBqc29uLm1vcnBoVGFyZ2V0cy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdFx0Z2VvbWV0cnkubW9ycGhUYXJnZXRzWyBpIF0gPSB7fTtcblx0XHRcdFx0XHRnZW9tZXRyeS5tb3JwaFRhcmdldHNbIGkgXS5uYW1lID0ganNvbi5tb3JwaFRhcmdldHNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdGdlb21ldHJ5Lm1vcnBoVGFyZ2V0c1sgaSBdLnZlcnRpY2VzID0gW107XG5cblx0XHRcdFx0XHR2YXIgZHN0VmVydGljZXMgPSBnZW9tZXRyeS5tb3JwaFRhcmdldHNbIGkgXS52ZXJ0aWNlcztcblx0XHRcdFx0XHR2YXIgc3JjVmVydGljZXMgPSBqc29uLm1vcnBoVGFyZ2V0c1sgaSBdLnZlcnRpY2VzO1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIHYgPSAwLCB2bCA9IHNyY1ZlcnRpY2VzLmxlbmd0aDsgdiA8IHZsOyB2ICs9IDMgKSB7XG5cblx0XHRcdFx0XHRcdHZhciB2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXHRcdFx0XHRcdFx0dmVydGV4LnggPSBzcmNWZXJ0aWNlc1sgdiBdICogc2NhbGU7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXgueSA9IHNyY1ZlcnRpY2VzWyB2ICsgMSBdICogc2NhbGU7XG5cdFx0XHRcdFx0XHR2ZXJ0ZXgueiA9IHNyY1ZlcnRpY2VzWyB2ICsgMiBdICogc2NhbGU7XG5cblx0XHRcdFx0XHRcdGRzdFZlcnRpY2VzLnB1c2goIHZlcnRleCApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGpzb24ubW9ycGhDb2xvcnMgIT09IHVuZGVmaW5lZCAmJiBqc29uLm1vcnBoQ29sb3JzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuSlNPTkxvYWRlcjogXCJtb3JwaENvbG9yc1wiIG5vIGxvbmdlciBzdXBwb3J0ZWQuIFVzaW5nIHRoZW0gYXMgZmFjZSBjb2xvcnMuJyApO1xuXG5cdFx0XHRcdHZhciBmYWNlcyA9IGdlb21ldHJ5LmZhY2VzO1xuXHRcdFx0XHR2YXIgbW9ycGhDb2xvcnMgPSBqc29uLm1vcnBoQ29sb3JzWyAwIF0uY29sb3JzO1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGZhY2VzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRmYWNlc1sgaSBdLmNvbG9yLmZyb21BcnJheSggbW9ycGhDb2xvcnMsIGkgKiAzICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBwYXJzZUFuaW1hdGlvbnMoIGpzb24sIGdlb21ldHJ5ICkge1xuXG5cdFx0XHR2YXIgb3V0cHV0QW5pbWF0aW9ucyA9IFtdO1xuXG5cdFx0XHQvLyBwYXJzZSBvbGQgc3R5bGUgQm9uZS9IaWVyYXJjaHkgYW5pbWF0aW9uc1xuXHRcdFx0dmFyIGFuaW1hdGlvbnMgPSBbXTtcblxuXHRcdFx0aWYgKCBqc29uLmFuaW1hdGlvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGFuaW1hdGlvbnMucHVzaCgganNvbi5hbmltYXRpb24gKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGpzb24uYW5pbWF0aW9ucyAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGlmICgganNvbi5hbmltYXRpb25zLmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdGFuaW1hdGlvbnMgPSBhbmltYXRpb25zLmNvbmNhdCgganNvbi5hbmltYXRpb25zICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdGFuaW1hdGlvbnMucHVzaCgganNvbi5hbmltYXRpb25zICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGFuaW1hdGlvbnMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHRcdHZhciBjbGlwID0gQW5pbWF0aW9uQ2xpcC5wYXJzZUFuaW1hdGlvbiggYW5pbWF0aW9uc1sgaSBdLCBnZW9tZXRyeS5ib25lcyApO1xuXHRcdFx0XHRpZiAoIGNsaXAgKSBvdXRwdXRBbmltYXRpb25zLnB1c2goIGNsaXAgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBwYXJzZSBpbXBsaWNpdCBtb3JwaCBhbmltYXRpb25zXG5cdFx0XHRpZiAoIGdlb21ldHJ5Lm1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0XHQvLyBUT0RPOiBGaWd1cmUgb3V0IHdoYXQgYW4gYXBwcm9wcmFpdGUgRlBTIGlzIGZvciBtb3JwaCB0YXJnZXQgYW5pbWF0aW9ucyAtLSBkZWZhdWx0aW5nIHRvIDEwLCBidXQgcmVhbGx5IGl0IGlzIGNvbXBsZXRlbHkgYXJiaXRyYXJ5LlxuXHRcdFx0XHR2YXIgbW9ycGhBbmltYXRpb25DbGlwcyA9IEFuaW1hdGlvbkNsaXAuQ3JlYXRlQ2xpcHNGcm9tTW9ycGhUYXJnZXRTZXF1ZW5jZXMoIGdlb21ldHJ5Lm1vcnBoVGFyZ2V0cywgMTAgKTtcblx0XHRcdFx0b3V0cHV0QW5pbWF0aW9ucyA9IG91dHB1dEFuaW1hdGlvbnMuY29uY2F0KCBtb3JwaEFuaW1hdGlvbkNsaXBzICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvdXRwdXRBbmltYXRpb25zLmxlbmd0aCA+IDAgKSBnZW9tZXRyeS5hbmltYXRpb25zID0gb3V0cHV0QW5pbWF0aW9ucztcblxuXHRcdH1cblxuXHRcdHJldHVybiBmdW5jdGlvbiAoIGpzb24sIHRleHR1cmVQYXRoICkge1xuXG5cdFx0XHRpZiAoIGpzb24uZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdC8vIEdlb21ldHJ5IDQuMCBzcGVjXG5cdFx0XHRcdGpzb24gPSBqc29uLmRhdGE7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBqc29uLnNjYWxlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0anNvbi5zY2FsZSA9IDEuMCAvIGpzb24uc2NhbGU7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0anNvbi5zY2FsZSA9IDEuMDtcblxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZ2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoKTtcblxuXHRcdFx0cGFyc2VNb2RlbCgganNvbiwgZ2VvbWV0cnkgKTtcblx0XHRcdHBhcnNlU2tpbigganNvbiwgZ2VvbWV0cnkgKTtcblx0XHRcdHBhcnNlTW9ycGhpbmcoIGpzb24sIGdlb21ldHJ5ICk7XG5cdFx0XHRwYXJzZUFuaW1hdGlvbnMoIGpzb24sIGdlb21ldHJ5ICk7XG5cblx0XHRcdGdlb21ldHJ5LmNvbXB1dGVGYWNlTm9ybWFscygpO1xuXHRcdFx0Z2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKCk7XG5cblx0XHRcdGlmICgganNvbi5tYXRlcmlhbHMgPT09IHVuZGVmaW5lZCB8fCBqc29uLm1hdGVyaWFscy5sZW5ndGggPT09IDAgKSB7XG5cblx0XHRcdFx0cmV0dXJuIHsgZ2VvbWV0cnk6IGdlb21ldHJ5IH07XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dmFyIG1hdGVyaWFscyA9IExvYWRlci5wcm90b3R5cGUuaW5pdE1hdGVyaWFscygganNvbi5tYXRlcmlhbHMsIHRleHR1cmVQYXRoLCB0aGlzLmNyb3NzT3JpZ2luICk7XG5cblx0XHRcdFx0cmV0dXJuIHsgZ2VvbWV0cnk6IGdlb21ldHJ5LCBtYXRlcmlhbHM6IG1hdGVyaWFscyB9O1xuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdH0gKSgpXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIE9iamVjdExvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblx0dGhpcy50ZXh0dXJlUGF0aCA9ICcnO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIE9iamVjdExvYWRlci5wcm90b3R5cGUsIHtcblxuXHRsb2FkOiBmdW5jdGlvbiAoIHVybCwgb25Mb2FkLCBvblByb2dyZXNzLCBvbkVycm9yICkge1xuXG5cdFx0aWYgKCB0aGlzLnRleHR1cmVQYXRoID09PSAnJyApIHtcblxuXHRcdFx0dGhpcy50ZXh0dXJlUGF0aCA9IHVybC5zdWJzdHJpbmcoIDAsIHVybC5sYXN0SW5kZXhPZiggJy8nICkgKyAxICk7XG5cblx0XHR9XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGxvYWRlciA9IG5ldyBGaWxlTG9hZGVyKCBzY29wZS5tYW5hZ2VyICk7XG5cdFx0bG9hZGVyLmxvYWQoIHVybCwgZnVuY3Rpb24gKCB0ZXh0ICkge1xuXG5cdFx0XHR2YXIganNvbiA9IG51bGw7XG5cblx0XHRcdHRyeSB7XG5cblx0XHRcdFx0anNvbiA9IEpTT04ucGFyc2UoIHRleHQgKTtcblxuXHRcdFx0fSBjYXRjaCAoIGVycm9yICkge1xuXG5cdFx0XHRcdGlmICggb25FcnJvciAhPT0gdW5kZWZpbmVkICkgb25FcnJvciggZXJyb3IgKTtcblxuXHRcdFx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUU6T2JqZWN0TG9hZGVyOiBDYW5cXCd0IHBhcnNlICcgKyB1cmwgKyAnLicsIGVycm9yLm1lc3NhZ2UgKTtcblxuXHRcdFx0XHRyZXR1cm47XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIG1ldGFkYXRhID0ganNvbi5tZXRhZGF0YTtcblxuXHRcdFx0aWYgKCBtZXRhZGF0YSA9PT0gdW5kZWZpbmVkIHx8IG1ldGFkYXRhLnR5cGUgPT09IHVuZGVmaW5lZCB8fCBtZXRhZGF0YS50eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdnZW9tZXRyeScgKSB7XG5cblx0XHRcdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLk9iamVjdExvYWRlcjogQ2FuXFwndCBsb2FkICcgKyB1cmwgKyAnLiBVc2UgVEhSRUUuSlNPTkxvYWRlciBpbnN0ZWFkLicgKTtcblx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHR9XG5cblx0XHRcdHNjb3BlLnBhcnNlKCBqc29uLCBvbkxvYWQgKTtcblxuXHRcdH0sIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKTtcblxuXHR9LFxuXG5cdHNldFRleHR1cmVQYXRoOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy50ZXh0dXJlUGF0aCA9IHZhbHVlO1xuXG5cdH0sXG5cblx0c2V0Q3Jvc3NPcmlnaW46IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLmNyb3NzT3JpZ2luID0gdmFsdWU7XG5cblx0fSxcblxuXHRwYXJzZTogZnVuY3Rpb24gKCBqc29uLCBvbkxvYWQgKSB7XG5cblx0XHR2YXIgZ2VvbWV0cmllcyA9IHRoaXMucGFyc2VHZW9tZXRyaWVzKCBqc29uLmdlb21ldHJpZXMgKTtcblxuXHRcdHZhciBpbWFnZXMgPSB0aGlzLnBhcnNlSW1hZ2VzKCBqc29uLmltYWdlcywgZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRpZiAoIG9uTG9hZCAhPT0gdW5kZWZpbmVkICkgb25Mb2FkKCBvYmplY3QgKTtcblxuXHRcdH0gKTtcblxuXHRcdHZhciB0ZXh0dXJlcyA9IHRoaXMucGFyc2VUZXh0dXJlcygganNvbi50ZXh0dXJlcywgaW1hZ2VzICk7XG5cdFx0dmFyIG1hdGVyaWFscyA9IHRoaXMucGFyc2VNYXRlcmlhbHMoIGpzb24ubWF0ZXJpYWxzLCB0ZXh0dXJlcyApO1xuXG5cdFx0dmFyIG9iamVjdCA9IHRoaXMucGFyc2VPYmplY3QoIGpzb24ub2JqZWN0LCBnZW9tZXRyaWVzLCBtYXRlcmlhbHMgKTtcblxuXHRcdGlmICgganNvbi5hbmltYXRpb25zICkge1xuXG5cdFx0XHRvYmplY3QuYW5pbWF0aW9ucyA9IHRoaXMucGFyc2VBbmltYXRpb25zKCBqc29uLmFuaW1hdGlvbnMgKTtcblxuXHRcdH1cblxuXHRcdGlmICgganNvbi5pbWFnZXMgPT09IHVuZGVmaW5lZCB8fCBqc29uLmltYWdlcy5sZW5ndGggPT09IDAgKSB7XG5cblx0XHRcdGlmICggb25Mb2FkICE9PSB1bmRlZmluZWQgKSBvbkxvYWQoIG9iamVjdCApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iamVjdDtcblxuXHR9LFxuXG5cdHBhcnNlR2VvbWV0cmllczogZnVuY3Rpb24gKCBqc29uICkge1xuXG5cdFx0dmFyIGdlb21ldHJpZXMgPSB7fTtcblxuXHRcdGlmICgganNvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgZ2VvbWV0cnlMb2FkZXIgPSBuZXcgSlNPTkxvYWRlcigpO1xuXHRcdFx0dmFyIGJ1ZmZlckdlb21ldHJ5TG9hZGVyID0gbmV3IEJ1ZmZlckdlb21ldHJ5TG9hZGVyKCk7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGpzb24ubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHR2YXIgZ2VvbWV0cnk7XG5cdFx0XHRcdHZhciBkYXRhID0ganNvblsgaSBdO1xuXG5cdFx0XHRcdHN3aXRjaCAoIGRhdGEudHlwZSApIHtcblxuXHRcdFx0XHRcdGNhc2UgJ1BsYW5lR2VvbWV0cnknOlxuXHRcdFx0XHRcdGNhc2UgJ1BsYW5lQnVmZmVyR2VvbWV0cnknOlxuXG5cdFx0XHRcdFx0XHRnZW9tZXRyeSA9IG5ldyBHZW9tZXRyaWVzWyBkYXRhLnR5cGUgXShcblx0XHRcdFx0XHRcdFx0ZGF0YS53aWR0aCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5oZWlnaHQsXG5cdFx0XHRcdFx0XHRcdGRhdGEud2lkdGhTZWdtZW50cyxcblx0XHRcdFx0XHRcdFx0ZGF0YS5oZWlnaHRTZWdtZW50c1xuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdCb3hHZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnQm94QnVmZmVyR2VvbWV0cnknOlxuXHRcdFx0XHRcdGNhc2UgJ0N1YmVHZW9tZXRyeSc6IC8vIGJhY2t3YXJkcyBjb21wYXRpYmxlXG5cblx0XHRcdFx0XHRcdGdlb21ldHJ5ID0gbmV3IEdlb21ldHJpZXNbIGRhdGEudHlwZSBdKFxuXHRcdFx0XHRcdFx0XHRkYXRhLndpZHRoLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmhlaWdodCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5kZXB0aCxcblx0XHRcdFx0XHRcdFx0ZGF0YS53aWR0aFNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmhlaWdodFNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmRlcHRoU2VnbWVudHNcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0Y2FzZSAnQ2lyY2xlR2VvbWV0cnknOlxuXHRcdFx0XHRcdGNhc2UgJ0NpcmNsZUJ1ZmZlckdlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBuZXcgR2VvbWV0cmllc1sgZGF0YS50eXBlIF0oXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLnNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLnRoZXRhU3RhcnQsXG5cdFx0XHRcdFx0XHRcdGRhdGEudGhldGFMZW5ndGhcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0Y2FzZSAnQ3lsaW5kZXJHZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnQ3lsaW5kZXJCdWZmZXJHZW9tZXRyeSc6XG5cblx0XHRcdFx0XHRcdGdlb21ldHJ5ID0gbmV3IEdlb21ldHJpZXNbIGRhdGEudHlwZSBdKFxuXHRcdFx0XHRcdFx0XHRkYXRhLnJhZGl1c1RvcCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5yYWRpdXNCb3R0b20sXG5cdFx0XHRcdFx0XHRcdGRhdGEuaGVpZ2h0LFxuXHRcdFx0XHRcdFx0XHRkYXRhLnJhZGlhbFNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmhlaWdodFNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLm9wZW5FbmRlZCxcblx0XHRcdFx0XHRcdFx0ZGF0YS50aGV0YVN0YXJ0LFxuXHRcdFx0XHRcdFx0XHRkYXRhLnRoZXRhTGVuZ3RoXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgJ0NvbmVHZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnQ29uZUJ1ZmZlckdlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBuZXcgR2VvbWV0cmllc1sgZGF0YS50eXBlIF0oXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmhlaWdodCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5yYWRpYWxTZWdtZW50cyxcblx0XHRcdFx0XHRcdFx0ZGF0YS5oZWlnaHRTZWdtZW50cyxcblx0XHRcdFx0XHRcdFx0ZGF0YS5vcGVuRW5kZWQsXG5cdFx0XHRcdFx0XHRcdGRhdGEudGhldGFTdGFydCxcblx0XHRcdFx0XHRcdFx0ZGF0YS50aGV0YUxlbmd0aFxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdTcGhlcmVHZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnU3BoZXJlQnVmZmVyR2VvbWV0cnknOlxuXG5cdFx0XHRcdFx0XHRnZW9tZXRyeSA9IG5ldyBHZW9tZXRyaWVzWyBkYXRhLnR5cGUgXShcblx0XHRcdFx0XHRcdFx0ZGF0YS5yYWRpdXMsXG5cdFx0XHRcdFx0XHRcdGRhdGEud2lkdGhTZWdtZW50cyxcblx0XHRcdFx0XHRcdFx0ZGF0YS5oZWlnaHRTZWdtZW50cyxcblx0XHRcdFx0XHRcdFx0ZGF0YS5waGlTdGFydCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5waGlMZW5ndGgsXG5cdFx0XHRcdFx0XHRcdGRhdGEudGhldGFTdGFydCxcblx0XHRcdFx0XHRcdFx0ZGF0YS50aGV0YUxlbmd0aFxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdEb2RlY2FoZWRyb25HZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnSWNvc2FoZWRyb25HZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnT2N0YWhlZHJvbkdlb21ldHJ5Jzpcblx0XHRcdFx0XHRjYXNlICdUZXRyYWhlZHJvbkdlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBuZXcgR2VvbWV0cmllc1sgZGF0YS50eXBlIF0oXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmRldGFpbFxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdSaW5nR2VvbWV0cnknOlxuXHRcdFx0XHRcdGNhc2UgJ1JpbmdCdWZmZXJHZW9tZXRyeSc6XG5cblx0XHRcdFx0XHRcdGdlb21ldHJ5ID0gbmV3IEdlb21ldHJpZXNbIGRhdGEudHlwZSBdKFxuXHRcdFx0XHRcdFx0XHRkYXRhLmlubmVyUmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLm91dGVyUmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLnRoZXRhU2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEucGhpU2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEudGhldGFTdGFydCxcblx0XHRcdFx0XHRcdFx0ZGF0YS50aGV0YUxlbmd0aFxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdUb3J1c0dlb21ldHJ5Jzpcblx0XHRcdFx0XHRjYXNlICdUb3J1c0J1ZmZlckdlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBuZXcgR2VvbWV0cmllc1sgZGF0YS50eXBlIF0oXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLnR1YmUsXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaWFsU2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEudHVidWxhclNlZ21lbnRzLFxuXHRcdFx0XHRcdFx0XHRkYXRhLmFyY1xuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0XHRjYXNlICdUb3J1c0tub3RHZW9tZXRyeSc6XG5cdFx0XHRcdFx0Y2FzZSAnVG9ydXNLbm90QnVmZmVyR2VvbWV0cnknOlxuXG5cdFx0XHRcdFx0XHRnZW9tZXRyeSA9IG5ldyBHZW9tZXRyaWVzWyBkYXRhLnR5cGUgXShcblx0XHRcdFx0XHRcdFx0ZGF0YS5yYWRpdXMsXG5cdFx0XHRcdFx0XHRcdGRhdGEudHViZSxcblx0XHRcdFx0XHRcdFx0ZGF0YS50dWJ1bGFyU2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEucmFkaWFsU2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEucCxcblx0XHRcdFx0XHRcdFx0ZGF0YS5xXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgJ0xhdGhlR2VvbWV0cnknOlxuXHRcdFx0XHRcdGNhc2UgJ0xhdGhlQnVmZmVyR2VvbWV0cnknOlxuXG5cdFx0XHRcdFx0XHRnZW9tZXRyeSA9IG5ldyBHZW9tZXRyaWVzWyBkYXRhLnR5cGUgXShcblx0XHRcdFx0XHRcdFx0ZGF0YS5wb2ludHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEuc2VnbWVudHMsXG5cdFx0XHRcdFx0XHRcdGRhdGEucGhpU3RhcnQsXG5cdFx0XHRcdFx0XHRcdGRhdGEucGhpTGVuZ3RoXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgJ0J1ZmZlckdlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBidWZmZXJHZW9tZXRyeUxvYWRlci5wYXJzZSggZGF0YSApO1xuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGNhc2UgJ0dlb21ldHJ5JzpcblxuXHRcdFx0XHRcdFx0Z2VvbWV0cnkgPSBnZW9tZXRyeUxvYWRlci5wYXJzZSggZGF0YSwgdGhpcy50ZXh0dXJlUGF0aCApLmdlb21ldHJ5O1xuXG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cblx0XHRcdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdExvYWRlcjogVW5zdXBwb3J0ZWQgZ2VvbWV0cnkgdHlwZSBcIicgKyBkYXRhLnR5cGUgKyAnXCInICk7XG5cblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRnZW9tZXRyeS51dWlkID0gZGF0YS51dWlkO1xuXG5cdFx0XHRcdGlmICggZGF0YS5uYW1lICE9PSB1bmRlZmluZWQgKSBnZW9tZXRyeS5uYW1lID0gZGF0YS5uYW1lO1xuXG5cdFx0XHRcdGdlb21ldHJpZXNbIGRhdGEudXVpZCBdID0gZ2VvbWV0cnk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiBnZW9tZXRyaWVzO1xuXG5cdH0sXG5cblx0cGFyc2VNYXRlcmlhbHM6IGZ1bmN0aW9uICgganNvbiwgdGV4dHVyZXMgKSB7XG5cblx0XHR2YXIgbWF0ZXJpYWxzID0ge307XG5cblx0XHRpZiAoIGpzb24gIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dmFyIGxvYWRlciA9IG5ldyBNYXRlcmlhbExvYWRlcigpO1xuXHRcdFx0bG9hZGVyLnNldFRleHR1cmVzKCB0ZXh0dXJlcyApO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBqc29uLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGRhdGEgPSBqc29uWyBpIF07XG5cblx0XHRcdFx0aWYgKCBkYXRhLnR5cGUgPT09ICdNdWx0aU1hdGVyaWFsJyApIHtcblxuXHRcdFx0XHRcdC8vIERlcHJlY2F0ZWRcblxuXHRcdFx0XHRcdHZhciBhcnJheSA9IFtdO1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgZGF0YS5tYXRlcmlhbHMubGVuZ3RoOyBqICsrICkge1xuXG5cdFx0XHRcdFx0XHRhcnJheS5wdXNoKCBsb2FkZXIucGFyc2UoIGRhdGEubWF0ZXJpYWxzWyBqIF0gKSApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0bWF0ZXJpYWxzWyBkYXRhLnV1aWQgXSA9IGFycmF5O1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRtYXRlcmlhbHNbIGRhdGEudXVpZCBdID0gbG9hZGVyLnBhcnNlKCBkYXRhICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0ZXJpYWxzO1xuXG5cdH0sXG5cblx0cGFyc2VBbmltYXRpb25zOiBmdW5jdGlvbiAoIGpzb24gKSB7XG5cblx0XHR2YXIgYW5pbWF0aW9ucyA9IFtdO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwganNvbi5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdHZhciBjbGlwID0gQW5pbWF0aW9uQ2xpcC5wYXJzZSgganNvblsgaSBdICk7XG5cblx0XHRcdGFuaW1hdGlvbnMucHVzaCggY2xpcCApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFuaW1hdGlvbnM7XG5cblx0fSxcblxuXHRwYXJzZUltYWdlczogZnVuY3Rpb24gKCBqc29uLCBvbkxvYWQgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXHRcdHZhciBpbWFnZXMgPSB7fTtcblxuXHRcdGZ1bmN0aW9uIGxvYWRJbWFnZSggdXJsICkge1xuXG5cdFx0XHRzY29wZS5tYW5hZ2VyLml0ZW1TdGFydCggdXJsICk7XG5cblx0XHRcdHJldHVybiBsb2FkZXIubG9hZCggdXJsLCBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRW5kKCB1cmwgKTtcblxuXHRcdFx0fSwgdW5kZWZpbmVkLCBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRW5kKCB1cmwgKTtcblx0XHRcdFx0c2NvcGUubWFuYWdlci5pdGVtRXJyb3IoIHVybCApO1xuXG5cdFx0XHR9ICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIGpzb24gIT09IHVuZGVmaW5lZCAmJiBqc29uLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdHZhciBtYW5hZ2VyID0gbmV3IExvYWRpbmdNYW5hZ2VyKCBvbkxvYWQgKTtcblxuXHRcdFx0dmFyIGxvYWRlciA9IG5ldyBJbWFnZUxvYWRlciggbWFuYWdlciApO1xuXHRcdFx0bG9hZGVyLnNldENyb3NzT3JpZ2luKCB0aGlzLmNyb3NzT3JpZ2luICk7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGpzb24ubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHR2YXIgaW1hZ2UgPSBqc29uWyBpIF07XG5cdFx0XHRcdHZhciBwYXRoID0gL14oXFwvXFwvKXwoW2Etel0rOihcXC9cXC8pPykvaS50ZXN0KCBpbWFnZS51cmwgKSA/IGltYWdlLnVybCA6IHNjb3BlLnRleHR1cmVQYXRoICsgaW1hZ2UudXJsO1xuXG5cdFx0XHRcdGltYWdlc1sgaW1hZ2UudXVpZCBdID0gbG9hZEltYWdlKCBwYXRoICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiBpbWFnZXM7XG5cblx0fSxcblxuXHRwYXJzZVRleHR1cmVzOiBmdW5jdGlvbiAoIGpzb24sIGltYWdlcyApIHtcblxuXHRcdGZ1bmN0aW9uIHBhcnNlQ29uc3RhbnQoIHZhbHVlLCB0eXBlICkge1xuXG5cdFx0XHRpZiAoIHR5cGVvZiggdmFsdWUgKSA9PT0gJ251bWJlcicgKSByZXR1cm4gdmFsdWU7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdExvYWRlci5wYXJzZVRleHR1cmU6IENvbnN0YW50IHNob3VsZCBiZSBpbiBudW1lcmljIGZvcm0uJywgdmFsdWUgKTtcblxuXHRcdFx0cmV0dXJuIHR5cGVbIHZhbHVlIF07XG5cblx0XHR9XG5cblx0XHR2YXIgdGV4dHVyZXMgPSB7fTtcblxuXHRcdGlmICgganNvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBqc29uLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGRhdGEgPSBqc29uWyBpIF07XG5cblx0XHRcdFx0aWYgKCBkYXRhLmltYWdlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3RMb2FkZXI6IE5vIFwiaW1hZ2VcIiBzcGVjaWZpZWQgZm9yJywgZGF0YS51dWlkICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggaW1hZ2VzWyBkYXRhLmltYWdlIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdExvYWRlcjogVW5kZWZpbmVkIGltYWdlJywgZGF0YS5pbWFnZSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgdGV4dHVyZSA9IG5ldyBUZXh0dXJlKCBpbWFnZXNbIGRhdGEuaW1hZ2UgXSApO1xuXHRcdFx0XHR0ZXh0dXJlLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0XHR0ZXh0dXJlLnV1aWQgPSBkYXRhLnV1aWQ7XG5cblx0XHRcdFx0aWYgKCBkYXRhLm5hbWUgIT09IHVuZGVmaW5lZCApIHRleHR1cmUubmFtZSA9IGRhdGEubmFtZTtcblxuXHRcdFx0XHRpZiAoIGRhdGEubWFwcGluZyAhPT0gdW5kZWZpbmVkICkgdGV4dHVyZS5tYXBwaW5nID0gcGFyc2VDb25zdGFudCggZGF0YS5tYXBwaW5nLCBURVhUVVJFX01BUFBJTkcgKTtcblxuXHRcdFx0XHRpZiAoIGRhdGEub2Zmc2V0ICE9PSB1bmRlZmluZWQgKSB0ZXh0dXJlLm9mZnNldC5mcm9tQXJyYXkoIGRhdGEub2Zmc2V0ICk7XG5cdFx0XHRcdGlmICggZGF0YS5yZXBlYXQgIT09IHVuZGVmaW5lZCApIHRleHR1cmUucmVwZWF0LmZyb21BcnJheSggZGF0YS5yZXBlYXQgKTtcblx0XHRcdFx0aWYgKCBkYXRhLndyYXAgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdHRleHR1cmUud3JhcFMgPSBwYXJzZUNvbnN0YW50KCBkYXRhLndyYXBbIDAgXSwgVEVYVFVSRV9XUkFQUElORyApO1xuXHRcdFx0XHRcdHRleHR1cmUud3JhcFQgPSBwYXJzZUNvbnN0YW50KCBkYXRhLndyYXBbIDEgXSwgVEVYVFVSRV9XUkFQUElORyApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGRhdGEubWluRmlsdGVyICE9PSB1bmRlZmluZWQgKSB0ZXh0dXJlLm1pbkZpbHRlciA9IHBhcnNlQ29uc3RhbnQoIGRhdGEubWluRmlsdGVyLCBURVhUVVJFX0ZJTFRFUiApO1xuXHRcdFx0XHRpZiAoIGRhdGEubWFnRmlsdGVyICE9PSB1bmRlZmluZWQgKSB0ZXh0dXJlLm1hZ0ZpbHRlciA9IHBhcnNlQ29uc3RhbnQoIGRhdGEubWFnRmlsdGVyLCBURVhUVVJFX0ZJTFRFUiApO1xuXHRcdFx0XHRpZiAoIGRhdGEuYW5pc290cm9weSAhPT0gdW5kZWZpbmVkICkgdGV4dHVyZS5hbmlzb3Ryb3B5ID0gZGF0YS5hbmlzb3Ryb3B5O1xuXG5cdFx0XHRcdGlmICggZGF0YS5mbGlwWSAhPT0gdW5kZWZpbmVkICkgdGV4dHVyZS5mbGlwWSA9IGRhdGEuZmxpcFk7XG5cblx0XHRcdFx0dGV4dHVyZXNbIGRhdGEudXVpZCBdID0gdGV4dHVyZTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRleHR1cmVzO1xuXG5cdH0sXG5cblx0cGFyc2VPYmplY3Q6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBtYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHBhcnNlT2JqZWN0KCBkYXRhLCBnZW9tZXRyaWVzLCBtYXRlcmlhbHMgKSB7XG5cblx0XHRcdHZhciBvYmplY3Q7XG5cblx0XHRcdGZ1bmN0aW9uIGdldEdlb21ldHJ5KCBuYW1lICkge1xuXG5cdFx0XHRcdGlmICggZ2VvbWV0cmllc1sgbmFtZSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3RMb2FkZXI6IFVuZGVmaW5lZCBnZW9tZXRyeScsIG5hbWUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGdlb21ldHJpZXNbIG5hbWUgXTtcblxuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBnZXRNYXRlcmlhbCggbmFtZSApIHtcblxuXHRcdFx0XHRpZiAoIG5hbWUgPT09IHVuZGVmaW5lZCApIHJldHVybiB1bmRlZmluZWQ7XG5cblx0XHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBuYW1lICkgKSB7XG5cblx0XHRcdFx0XHR2YXIgYXJyYXkgPSBbXTtcblxuXHRcdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IG5hbWUubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRcdFx0dmFyIHV1aWQgPSBuYW1lWyBpIF07XG5cblx0XHRcdFx0XHRcdGlmICggbWF0ZXJpYWxzWyB1dWlkIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3RMb2FkZXI6IFVuZGVmaW5lZCBtYXRlcmlhbCcsIHV1aWQgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRhcnJheS5wdXNoKCBtYXRlcmlhbHNbIHV1aWQgXSApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIGFycmF5O1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIG1hdGVyaWFsc1sgbmFtZSBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3RMb2FkZXI6IFVuZGVmaW5lZCBtYXRlcmlhbCcsIG5hbWUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIG1hdGVyaWFsc1sgbmFtZSBdO1xuXG5cdFx0XHR9XG5cblx0XHRcdHN3aXRjaCAoIGRhdGEudHlwZSApIHtcblxuXHRcdFx0XHRjYXNlICdTY2VuZSc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgU2NlbmUoKTtcblxuXHRcdFx0XHRcdGlmICggZGF0YS5iYWNrZ3JvdW5kICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdGlmICggTnVtYmVyLmlzSW50ZWdlciggZGF0YS5iYWNrZ3JvdW5kICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0b2JqZWN0LmJhY2tncm91bmQgPSBuZXcgQ29sb3IoIGRhdGEuYmFja2dyb3VuZCApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGRhdGEuZm9nICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdGlmICggZGF0YS5mb2cudHlwZSA9PT0gJ0ZvZycgKSB7XG5cblx0XHRcdFx0XHRcdFx0b2JqZWN0LmZvZyA9IG5ldyBGb2coIGRhdGEuZm9nLmNvbG9yLCBkYXRhLmZvZy5uZWFyLCBkYXRhLmZvZy5mYXIgKTtcblxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggZGF0YS5mb2cudHlwZSA9PT0gJ0ZvZ0V4cDInICkge1xuXG5cdFx0XHRcdFx0XHRcdG9iamVjdC5mb2cgPSBuZXcgRm9nRXhwMiggZGF0YS5mb2cuY29sb3IsIGRhdGEuZm9nLmRlbnNpdHkgKTtcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnUGVyc3BlY3RpdmVDYW1lcmEnOlxuXG5cdFx0XHRcdFx0b2JqZWN0ID0gbmV3IFBlcnNwZWN0aXZlQ2FtZXJhKCBkYXRhLmZvdiwgZGF0YS5hc3BlY3QsIGRhdGEubmVhciwgZGF0YS5mYXIgKTtcblxuXHRcdFx0XHRcdGlmICggZGF0YS5mb2N1cyAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LmZvY3VzID0gZGF0YS5mb2N1cztcblx0XHRcdFx0XHRpZiAoIGRhdGEuem9vbSAhPT0gdW5kZWZpbmVkICkgb2JqZWN0Lnpvb20gPSBkYXRhLnpvb207XG5cdFx0XHRcdFx0aWYgKCBkYXRhLmZpbG1HYXVnZSAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LmZpbG1HYXVnZSA9IGRhdGEuZmlsbUdhdWdlO1xuXHRcdFx0XHRcdGlmICggZGF0YS5maWxtT2Zmc2V0ICE9PSB1bmRlZmluZWQgKSBvYmplY3QuZmlsbU9mZnNldCA9IGRhdGEuZmlsbU9mZnNldDtcblx0XHRcdFx0XHRpZiAoIGRhdGEudmlldyAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LnZpZXcgPSBPYmplY3QuYXNzaWduKCB7fSwgZGF0YS52aWV3ICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdPcnRob2dyYXBoaWNDYW1lcmEnOlxuXG5cdFx0XHRcdFx0b2JqZWN0ID0gbmV3IE9ydGhvZ3JhcGhpY0NhbWVyYSggZGF0YS5sZWZ0LCBkYXRhLnJpZ2h0LCBkYXRhLnRvcCwgZGF0YS5ib3R0b20sIGRhdGEubmVhciwgZGF0YS5mYXIgKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ0FtYmllbnRMaWdodCc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgQW1iaWVudExpZ2h0KCBkYXRhLmNvbG9yLCBkYXRhLmludGVuc2l0eSApO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnRGlyZWN0aW9uYWxMaWdodCc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgRGlyZWN0aW9uYWxMaWdodCggZGF0YS5jb2xvciwgZGF0YS5pbnRlbnNpdHkgKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1BvaW50TGlnaHQnOlxuXG5cdFx0XHRcdFx0b2JqZWN0ID0gbmV3IFBvaW50TGlnaHQoIGRhdGEuY29sb3IsIGRhdGEuaW50ZW5zaXR5LCBkYXRhLmRpc3RhbmNlLCBkYXRhLmRlY2F5ICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdSZWN0QXJlYUxpZ2h0JzpcblxuXHRcdFx0XHRcdG9iamVjdCA9IG5ldyBSZWN0QXJlYUxpZ2h0KCBkYXRhLmNvbG9yLCBkYXRhLmludGVuc2l0eSwgZGF0YS53aWR0aCwgZGF0YS5oZWlnaHQgKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1Nwb3RMaWdodCc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgU3BvdExpZ2h0KCBkYXRhLmNvbG9yLCBkYXRhLmludGVuc2l0eSwgZGF0YS5kaXN0YW5jZSwgZGF0YS5hbmdsZSwgZGF0YS5wZW51bWJyYSwgZGF0YS5kZWNheSApO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnSGVtaXNwaGVyZUxpZ2h0JzpcblxuXHRcdFx0XHRcdG9iamVjdCA9IG5ldyBIZW1pc3BoZXJlTGlnaHQoIGRhdGEuY29sb3IsIGRhdGEuZ3JvdW5kQ29sb3IsIGRhdGEuaW50ZW5zaXR5ICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdTa2lubmVkTWVzaCc6XG5cblx0XHRcdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3RMb2FkZXIucGFyc2VPYmplY3QoKSBkb2VzIG5vdCBzdXBwb3J0IFNraW5uZWRNZXNoIHlldC4nICk7XG5cblx0XHRcdFx0Y2FzZSAnTWVzaCc6XG5cblx0XHRcdFx0XHR2YXIgZ2VvbWV0cnkgPSBnZXRHZW9tZXRyeSggZGF0YS5nZW9tZXRyeSApO1xuXHRcdFx0XHRcdHZhciBtYXRlcmlhbCA9IGdldE1hdGVyaWFsKCBkYXRhLm1hdGVyaWFsICk7XG5cblx0XHRcdFx0XHRpZiAoIGdlb21ldHJ5LmJvbmVzICYmIGdlb21ldHJ5LmJvbmVzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdFx0XHRcdG9iamVjdCA9IG5ldyBTa2lubmVkTWVzaCggZ2VvbWV0cnksIG1hdGVyaWFsICk7XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRvYmplY3QgPSBuZXcgTWVzaCggZ2VvbWV0cnksIG1hdGVyaWFsICk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdMT0QnOlxuXG5cdFx0XHRcdFx0b2JqZWN0ID0gbmV3IExPRCgpO1xuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnTGluZSc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgTGluZSggZ2V0R2VvbWV0cnkoIGRhdGEuZ2VvbWV0cnkgKSwgZ2V0TWF0ZXJpYWwoIGRhdGEubWF0ZXJpYWwgKSwgZGF0YS5tb2RlICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdMaW5lTG9vcCc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgTGluZUxvb3AoIGdldEdlb21ldHJ5KCBkYXRhLmdlb21ldHJ5ICksIGdldE1hdGVyaWFsKCBkYXRhLm1hdGVyaWFsICkgKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ0xpbmVTZWdtZW50cyc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgTGluZVNlZ21lbnRzKCBnZXRHZW9tZXRyeSggZGF0YS5nZW9tZXRyeSApLCBnZXRNYXRlcmlhbCggZGF0YS5tYXRlcmlhbCApICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdQb2ludENsb3VkJzpcblx0XHRcdFx0Y2FzZSAnUG9pbnRzJzpcblxuXHRcdFx0XHRcdG9iamVjdCA9IG5ldyBQb2ludHMoIGdldEdlb21ldHJ5KCBkYXRhLmdlb21ldHJ5ICksIGdldE1hdGVyaWFsKCBkYXRhLm1hdGVyaWFsICkgKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGNhc2UgJ1Nwcml0ZSc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgU3ByaXRlKCBnZXRNYXRlcmlhbCggZGF0YS5tYXRlcmlhbCApICk7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdHcm91cCc6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgR3JvdXAoKTtcblxuXHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdGRlZmF1bHQ6XG5cblx0XHRcdFx0XHRvYmplY3QgPSBuZXcgT2JqZWN0M0QoKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRvYmplY3QudXVpZCA9IGRhdGEudXVpZDtcblxuXHRcdFx0aWYgKCBkYXRhLm5hbWUgIT09IHVuZGVmaW5lZCApIG9iamVjdC5uYW1lID0gZGF0YS5uYW1lO1xuXHRcdFx0aWYgKCBkYXRhLm1hdHJpeCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdG1hdHJpeC5mcm9tQXJyYXkoIGRhdGEubWF0cml4ICk7XG5cdFx0XHRcdG1hdHJpeC5kZWNvbXBvc2UoIG9iamVjdC5wb3NpdGlvbiwgb2JqZWN0LnF1YXRlcm5pb24sIG9iamVjdC5zY2FsZSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGlmICggZGF0YS5wb3NpdGlvbiAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LnBvc2l0aW9uLmZyb21BcnJheSggZGF0YS5wb3NpdGlvbiApO1xuXHRcdFx0XHRpZiAoIGRhdGEucm90YXRpb24gIT09IHVuZGVmaW5lZCApIG9iamVjdC5yb3RhdGlvbi5mcm9tQXJyYXkoIGRhdGEucm90YXRpb24gKTtcblx0XHRcdFx0aWYgKCBkYXRhLnF1YXRlcm5pb24gIT09IHVuZGVmaW5lZCApIG9iamVjdC5xdWF0ZXJuaW9uLmZyb21BcnJheSggZGF0YS5xdWF0ZXJuaW9uICk7XG5cdFx0XHRcdGlmICggZGF0YS5zY2FsZSAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LnNjYWxlLmZyb21BcnJheSggZGF0YS5zY2FsZSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggZGF0YS5jYXN0U2hhZG93ICE9PSB1bmRlZmluZWQgKSBvYmplY3QuY2FzdFNoYWRvdyA9IGRhdGEuY2FzdFNoYWRvdztcblx0XHRcdGlmICggZGF0YS5yZWNlaXZlU2hhZG93ICE9PSB1bmRlZmluZWQgKSBvYmplY3QucmVjZWl2ZVNoYWRvdyA9IGRhdGEucmVjZWl2ZVNoYWRvdztcblxuXHRcdFx0aWYgKCBkYXRhLnNoYWRvdyApIHtcblxuXHRcdFx0XHRpZiAoIGRhdGEuc2hhZG93LmJpYXMgIT09IHVuZGVmaW5lZCApIG9iamVjdC5zaGFkb3cuYmlhcyA9IGRhdGEuc2hhZG93LmJpYXM7XG5cdFx0XHRcdGlmICggZGF0YS5zaGFkb3cucmFkaXVzICE9PSB1bmRlZmluZWQgKSBvYmplY3Quc2hhZG93LnJhZGl1cyA9IGRhdGEuc2hhZG93LnJhZGl1cztcblx0XHRcdFx0aWYgKCBkYXRhLnNoYWRvdy5tYXBTaXplICE9PSB1bmRlZmluZWQgKSBvYmplY3Quc2hhZG93Lm1hcFNpemUuZnJvbUFycmF5KCBkYXRhLnNoYWRvdy5tYXBTaXplICk7XG5cdFx0XHRcdGlmICggZGF0YS5zaGFkb3cuY2FtZXJhICE9PSB1bmRlZmluZWQgKSBvYmplY3Quc2hhZG93LmNhbWVyYSA9IHRoaXMucGFyc2VPYmplY3QoIGRhdGEuc2hhZG93LmNhbWVyYSApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGlmICggZGF0YS52aXNpYmxlICE9PSB1bmRlZmluZWQgKSBvYmplY3QudmlzaWJsZSA9IGRhdGEudmlzaWJsZTtcblx0XHRcdGlmICggZGF0YS51c2VyRGF0YSAhPT0gdW5kZWZpbmVkICkgb2JqZWN0LnVzZXJEYXRhID0gZGF0YS51c2VyRGF0YTtcblxuXHRcdFx0aWYgKCBkYXRhLmNoaWxkcmVuICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Zm9yICggdmFyIGNoaWxkIGluIGRhdGEuY2hpbGRyZW4gKSB7XG5cblx0XHRcdFx0XHRvYmplY3QuYWRkKCB0aGlzLnBhcnNlT2JqZWN0KCBkYXRhLmNoaWxkcmVuWyBjaGlsZCBdLCBnZW9tZXRyaWVzLCBtYXRlcmlhbHMgKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGRhdGEudHlwZSA9PT0gJ0xPRCcgKSB7XG5cblx0XHRcdFx0dmFyIGxldmVscyA9IGRhdGEubGV2ZWxzO1xuXG5cdFx0XHRcdGZvciAoIHZhciBsID0gMDsgbCA8IGxldmVscy5sZW5ndGg7IGwgKysgKSB7XG5cblx0XHRcdFx0XHR2YXIgbGV2ZWwgPSBsZXZlbHNbIGwgXTtcblx0XHRcdFx0XHR2YXIgY2hpbGQgPSBvYmplY3QuZ2V0T2JqZWN0QnlQcm9wZXJ0eSggJ3V1aWQnLCBsZXZlbC5vYmplY3QgKTtcblxuXHRcdFx0XHRcdGlmICggY2hpbGQgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdFx0b2JqZWN0LmFkZExldmVsKCBjaGlsZCwgbGV2ZWwuZGlzdGFuY2UgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG9iamVjdDtcblxuXHRcdH07XG5cblx0fSgpXG5cbn0gKTtcblxudmFyIFRFWFRVUkVfTUFQUElORyA9IHtcblx0VVZNYXBwaW5nOiBVVk1hcHBpbmcsXG5cdEN1YmVSZWZsZWN0aW9uTWFwcGluZzogQ3ViZVJlZmxlY3Rpb25NYXBwaW5nLFxuXHRDdWJlUmVmcmFjdGlvbk1hcHBpbmc6IEN1YmVSZWZyYWN0aW9uTWFwcGluZyxcblx0RXF1aXJlY3Rhbmd1bGFyUmVmbGVjdGlvbk1hcHBpbmc6IEVxdWlyZWN0YW5ndWxhclJlZmxlY3Rpb25NYXBwaW5nLFxuXHRFcXVpcmVjdGFuZ3VsYXJSZWZyYWN0aW9uTWFwcGluZzogRXF1aXJlY3Rhbmd1bGFyUmVmcmFjdGlvbk1hcHBpbmcsXG5cdFNwaGVyaWNhbFJlZmxlY3Rpb25NYXBwaW5nOiBTcGhlcmljYWxSZWZsZWN0aW9uTWFwcGluZyxcblx0Q3ViZVVWUmVmbGVjdGlvbk1hcHBpbmc6IEN1YmVVVlJlZmxlY3Rpb25NYXBwaW5nLFxuXHRDdWJlVVZSZWZyYWN0aW9uTWFwcGluZzogQ3ViZVVWUmVmcmFjdGlvbk1hcHBpbmdcbn07XG5cbnZhciBURVhUVVJFX1dSQVBQSU5HID0ge1xuXHRSZXBlYXRXcmFwcGluZzogUmVwZWF0V3JhcHBpbmcsXG5cdENsYW1wVG9FZGdlV3JhcHBpbmc6IENsYW1wVG9FZGdlV3JhcHBpbmcsXG5cdE1pcnJvcmVkUmVwZWF0V3JhcHBpbmc6IE1pcnJvcmVkUmVwZWF0V3JhcHBpbmdcbn07XG5cbnZhciBURVhUVVJFX0ZJTFRFUiA9IHtcblx0TmVhcmVzdEZpbHRlcjogTmVhcmVzdEZpbHRlcixcblx0TmVhcmVzdE1pcE1hcE5lYXJlc3RGaWx0ZXI6IE5lYXJlc3RNaXBNYXBOZWFyZXN0RmlsdGVyLFxuXHROZWFyZXN0TWlwTWFwTGluZWFyRmlsdGVyOiBOZWFyZXN0TWlwTWFwTGluZWFyRmlsdGVyLFxuXHRMaW5lYXJGaWx0ZXI6IExpbmVhckZpbHRlcixcblx0TGluZWFyTWlwTWFwTmVhcmVzdEZpbHRlcjogTGluZWFyTWlwTWFwTmVhcmVzdEZpbHRlcixcblx0TGluZWFyTWlwTWFwTGluZWFyRmlsdGVyOiBMaW5lYXJNaXBNYXBMaW5lYXJGaWx0ZXJcbn07XG5cbi8qKlxuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICpcbiAqIEJlemllciBDdXJ2ZXMgZm9ybXVsYXMgb2J0YWluZWQgZnJvbVxuICogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Cw6l6aWVyX2N1cnZlXG4gKi9cblxuZnVuY3Rpb24gQ2F0bXVsbFJvbSggdCwgcDAsIHAxLCBwMiwgcDMgKSB7XG5cblx0dmFyIHYwID0gKCBwMiAtIHAwICkgKiAwLjU7XG5cdHZhciB2MSA9ICggcDMgLSBwMSApICogMC41O1xuXHR2YXIgdDIgPSB0ICogdDtcblx0dmFyIHQzID0gdCAqIHQyO1xuXHRyZXR1cm4gKCAyICogcDEgLSAyICogcDIgKyB2MCArIHYxICkgKiB0MyArICggLSAzICogcDEgKyAzICogcDIgLSAyICogdjAgLSB2MSApICogdDIgKyB2MCAqIHQgKyBwMTtcblxufVxuXG4vL1xuXG5mdW5jdGlvbiBRdWFkcmF0aWNCZXppZXJQMCggdCwgcCApIHtcblxuXHR2YXIgayA9IDEgLSB0O1xuXHRyZXR1cm4gayAqIGsgKiBwO1xuXG59XG5cbmZ1bmN0aW9uIFF1YWRyYXRpY0JlemllclAxKCB0LCBwICkge1xuXG5cdHJldHVybiAyICogKCAxIC0gdCApICogdCAqIHA7XG5cbn1cblxuZnVuY3Rpb24gUXVhZHJhdGljQmV6aWVyUDIoIHQsIHAgKSB7XG5cblx0cmV0dXJuIHQgKiB0ICogcDtcblxufVxuXG5mdW5jdGlvbiBRdWFkcmF0aWNCZXppZXIoIHQsIHAwLCBwMSwgcDIgKSB7XG5cblx0cmV0dXJuIFF1YWRyYXRpY0JlemllclAwKCB0LCBwMCApICsgUXVhZHJhdGljQmV6aWVyUDEoIHQsIHAxICkgK1xuXHRcdFF1YWRyYXRpY0JlemllclAyKCB0LCBwMiApO1xuXG59XG5cbi8vXG5cbmZ1bmN0aW9uIEN1YmljQmV6aWVyUDAoIHQsIHAgKSB7XG5cblx0dmFyIGsgPSAxIC0gdDtcblx0cmV0dXJuIGsgKiBrICogayAqIHA7XG5cbn1cblxuZnVuY3Rpb24gQ3ViaWNCZXppZXJQMSggdCwgcCApIHtcblxuXHR2YXIgayA9IDEgLSB0O1xuXHRyZXR1cm4gMyAqIGsgKiBrICogdCAqIHA7XG5cbn1cblxuZnVuY3Rpb24gQ3ViaWNCZXppZXJQMiggdCwgcCApIHtcblxuXHRyZXR1cm4gMyAqICggMSAtIHQgKSAqIHQgKiB0ICogcDtcblxufVxuXG5mdW5jdGlvbiBDdWJpY0JlemllclAzKCB0LCBwICkge1xuXG5cdHJldHVybiB0ICogdCAqIHQgKiBwO1xuXG59XG5cbmZ1bmN0aW9uIEN1YmljQmV6aWVyKCB0LCBwMCwgcDEsIHAyLCBwMyApIHtcblxuXHRyZXR1cm4gQ3ViaWNCZXppZXJQMCggdCwgcDAgKSArIEN1YmljQmV6aWVyUDEoIHQsIHAxICkgKyBDdWJpY0JlemllclAyKCB0LCBwMiApICtcblx0XHRDdWJpY0JlemllclAzKCB0LCBwMyApO1xuXG59XG5cbi8qKlxuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICogRXh0ZW5zaWJsZSBjdXJ2ZSBvYmplY3RcbiAqXG4gKiBTb21lIGNvbW1vbiBvZiBjdXJ2ZSBtZXRob2RzOlxuICogLmdldFBvaW50KHQpLCBnZXRUYW5nZW50KHQpXG4gKiAuZ2V0UG9pbnRBdCh1KSwgZ2V0VGFuZ2VudEF0KHUpXG4gKiAuZ2V0UG9pbnRzKCksIC5nZXRTcGFjZWRQb2ludHMoKVxuICogLmdldExlbmd0aCgpXG4gKiAudXBkYXRlQXJjTGVuZ3RocygpXG4gKlxuICogVGhpcyBmb2xsb3dpbmcgY3VydmVzIGluaGVyaXQgZnJvbSBUSFJFRS5DdXJ2ZTpcbiAqXG4gKiAtLSAyRCBjdXJ2ZXMgLS1cbiAqIFRIUkVFLkFyY0N1cnZlXG4gKiBUSFJFRS5DdWJpY0JlemllckN1cnZlXG4gKiBUSFJFRS5FbGxpcHNlQ3VydmVcbiAqIFRIUkVFLkxpbmVDdXJ2ZVxuICogVEhSRUUuUXVhZHJhdGljQmV6aWVyQ3VydmVcbiAqIFRIUkVFLlNwbGluZUN1cnZlXG4gKlxuICogLS0gM0QgY3VydmVzIC0tXG4gKiBUSFJFRS5DYXRtdWxsUm9tQ3VydmUzXG4gKiBUSFJFRS5DdWJpY0JlemllckN1cnZlM1xuICogVEhSRUUuTGluZUN1cnZlM1xuICogVEhSRUUuUXVhZHJhdGljQmV6aWVyQ3VydmUzXG4gKlxuICogQSBzZXJpZXMgb2YgY3VydmVzIGNhbiBiZSByZXByZXNlbnRlZCBhcyBhIFRIUkVFLkN1cnZlUGF0aC5cbiAqXG4gKiovXG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICpcdEFic3RyYWN0IEN1cnZlIGJhc2UgY2xhc3NcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuZnVuY3Rpb24gQ3VydmUoKSB7XG5cblx0dGhpcy5hcmNMZW5ndGhEaXZpc2lvbnMgPSAyMDA7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQ3VydmUucHJvdG90eXBlLCB7XG5cblx0Ly8gVmlydHVhbCBiYXNlIGNsYXNzIG1ldGhvZCB0byBvdmVyd3JpdGUgYW5kIGltcGxlbWVudCBpbiBzdWJjbGFzc2VzXG5cdC8vXHQtIHQgWzAgLi4gMV1cblxuXHRnZXRQb2ludDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQ3VydmU6IC5nZXRQb2ludCgpIG5vdCBpbXBsZW1lbnRlZC4nICk7XG5cdFx0cmV0dXJuIG51bGw7XG5cblx0fSxcblxuXHQvLyBHZXQgcG9pbnQgYXQgcmVsYXRpdmUgcG9zaXRpb24gaW4gY3VydmUgYWNjb3JkaW5nIHRvIGFyYyBsZW5ndGhcblx0Ly8gLSB1IFswIC4uIDFdXG5cblx0Z2V0UG9pbnRBdDogZnVuY3Rpb24gKCB1ICkge1xuXG5cdFx0dmFyIHQgPSB0aGlzLmdldFV0b1RtYXBwaW5nKCB1ICk7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UG9pbnQoIHQgKTtcblxuXHR9LFxuXG5cdC8vIEdldCBzZXF1ZW5jZSBvZiBwb2ludHMgdXNpbmcgZ2V0UG9pbnQoIHQgKVxuXG5cdGdldFBvaW50czogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHRpZiAoIGRpdmlzaW9ucyA9PT0gdW5kZWZpbmVkICkgZGl2aXNpb25zID0gNTtcblxuXHRcdHZhciBwb2ludHMgPSBbXTtcblxuXHRcdGZvciAoIHZhciBkID0gMDsgZCA8PSBkaXZpc2lvbnM7IGQgKysgKSB7XG5cblx0XHRcdHBvaW50cy5wdXNoKCB0aGlzLmdldFBvaW50KCBkIC8gZGl2aXNpb25zICkgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiBwb2ludHM7XG5cblx0fSxcblxuXHQvLyBHZXQgc2VxdWVuY2Ugb2YgcG9pbnRzIHVzaW5nIGdldFBvaW50QXQoIHUgKVxuXG5cdGdldFNwYWNlZFBvaW50czogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHRpZiAoIGRpdmlzaW9ucyA9PT0gdW5kZWZpbmVkICkgZGl2aXNpb25zID0gNTtcblxuXHRcdHZhciBwb2ludHMgPSBbXTtcblxuXHRcdGZvciAoIHZhciBkID0gMDsgZCA8PSBkaXZpc2lvbnM7IGQgKysgKSB7XG5cblx0XHRcdHBvaW50cy5wdXNoKCB0aGlzLmdldFBvaW50QXQoIGQgLyBkaXZpc2lvbnMgKSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBvaW50cztcblxuXHR9LFxuXG5cdC8vIEdldCB0b3RhbCBjdXJ2ZSBhcmMgbGVuZ3RoXG5cblx0Z2V0TGVuZ3RoOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgbGVuZ3RocyA9IHRoaXMuZ2V0TGVuZ3RocygpO1xuXHRcdHJldHVybiBsZW5ndGhzWyBsZW5ndGhzLmxlbmd0aCAtIDEgXTtcblxuXHR9LFxuXG5cdC8vIEdldCBsaXN0IG9mIGN1bXVsYXRpdmUgc2VnbWVudCBsZW5ndGhzXG5cblx0Z2V0TGVuZ3RoczogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHRpZiAoIGRpdmlzaW9ucyA9PT0gdW5kZWZpbmVkICkgZGl2aXNpb25zID0gdGhpcy5hcmNMZW5ndGhEaXZpc2lvbnM7XG5cblx0XHRpZiAoIHRoaXMuY2FjaGVBcmNMZW5ndGhzICYmXG5cdFx0XHQoIHRoaXMuY2FjaGVBcmNMZW5ndGhzLmxlbmd0aCA9PT0gZGl2aXNpb25zICsgMSApICYmXG5cdFx0XHQhIHRoaXMubmVlZHNVcGRhdGUgKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLmNhY2hlQXJjTGVuZ3RocztcblxuXHRcdH1cblxuXHRcdHRoaXMubmVlZHNVcGRhdGUgPSBmYWxzZTtcblxuXHRcdHZhciBjYWNoZSA9IFtdO1xuXHRcdHZhciBjdXJyZW50LCBsYXN0ID0gdGhpcy5nZXRQb2ludCggMCApO1xuXHRcdHZhciBwLCBzdW0gPSAwO1xuXG5cdFx0Y2FjaGUucHVzaCggMCApO1xuXG5cdFx0Zm9yICggcCA9IDE7IHAgPD0gZGl2aXNpb25zOyBwICsrICkge1xuXG5cdFx0XHRjdXJyZW50ID0gdGhpcy5nZXRQb2ludCggcCAvIGRpdmlzaW9ucyApO1xuXHRcdFx0c3VtICs9IGN1cnJlbnQuZGlzdGFuY2VUbyggbGFzdCApO1xuXHRcdFx0Y2FjaGUucHVzaCggc3VtICk7XG5cdFx0XHRsYXN0ID0gY3VycmVudDtcblxuXHRcdH1cblxuXHRcdHRoaXMuY2FjaGVBcmNMZW5ndGhzID0gY2FjaGU7XG5cblx0XHRyZXR1cm4gY2FjaGU7IC8vIHsgc3VtczogY2FjaGUsIHN1bTogc3VtIH07IFN1bSBpcyBpbiB0aGUgbGFzdCBlbGVtZW50LlxuXG5cdH0sXG5cblx0dXBkYXRlQXJjTGVuZ3RoczogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cdFx0dGhpcy5nZXRMZW5ndGhzKCk7XG5cblx0fSxcblxuXHQvLyBHaXZlbiB1ICggMCAuLiAxICksIGdldCBhIHQgdG8gZmluZCBwLiBUaGlzIGdpdmVzIHlvdSBwb2ludHMgd2hpY2ggYXJlIGVxdWlkaXN0YW50XG5cblx0Z2V0VXRvVG1hcHBpbmc6IGZ1bmN0aW9uICggdSwgZGlzdGFuY2UgKSB7XG5cblx0XHR2YXIgYXJjTGVuZ3RocyA9IHRoaXMuZ2V0TGVuZ3RocygpO1xuXG5cdFx0dmFyIGkgPSAwLCBpbCA9IGFyY0xlbmd0aHMubGVuZ3RoO1xuXG5cdFx0dmFyIHRhcmdldEFyY0xlbmd0aDsgLy8gVGhlIHRhcmdldGVkIHUgZGlzdGFuY2UgdmFsdWUgdG8gZ2V0XG5cblx0XHRpZiAoIGRpc3RhbmNlICkge1xuXG5cdFx0XHR0YXJnZXRBcmNMZW5ndGggPSBkaXN0YW5jZTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRhcmdldEFyY0xlbmd0aCA9IHUgKiBhcmNMZW5ndGhzWyBpbCAtIDEgXTtcblxuXHRcdH1cblxuXHRcdC8vIGJpbmFyeSBzZWFyY2ggZm9yIHRoZSBpbmRleCB3aXRoIGxhcmdlc3QgdmFsdWUgc21hbGxlciB0aGFuIHRhcmdldCB1IGRpc3RhbmNlXG5cblx0XHR2YXIgbG93ID0gMCwgaGlnaCA9IGlsIC0gMSwgY29tcGFyaXNvbjtcblxuXHRcdHdoaWxlICggbG93IDw9IGhpZ2ggKSB7XG5cblx0XHRcdGkgPSBNYXRoLmZsb29yKCBsb3cgKyAoIGhpZ2ggLSBsb3cgKSAvIDIgKTsgLy8gbGVzcyBsaWtlbHkgdG8gb3ZlcmZsb3csIHRob3VnaCBwcm9iYWJseSBub3QgaXNzdWUgaGVyZSwgSlMgZG9lc24ndCByZWFsbHkgaGF2ZSBpbnRlZ2VycywgYWxsIG51bWJlcnMgYXJlIGZsb2F0c1xuXG5cdFx0XHRjb21wYXJpc29uID0gYXJjTGVuZ3Roc1sgaSBdIC0gdGFyZ2V0QXJjTGVuZ3RoO1xuXG5cdFx0XHRpZiAoIGNvbXBhcmlzb24gPCAwICkge1xuXG5cdFx0XHRcdGxvdyA9IGkgKyAxO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21wYXJpc29uID4gMCApIHtcblxuXHRcdFx0XHRoaWdoID0gaSAtIDE7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0aGlnaCA9IGk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdC8vIERPTkVcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0aSA9IGhpZ2g7XG5cblx0XHRpZiAoIGFyY0xlbmd0aHNbIGkgXSA9PT0gdGFyZ2V0QXJjTGVuZ3RoICkge1xuXG5cdFx0XHRyZXR1cm4gaSAvICggaWwgLSAxICk7XG5cblx0XHR9XG5cblx0XHQvLyB3ZSBjb3VsZCBnZXQgZmluZXIgZ3JhaW4gYXQgbGVuZ3Rocywgb3IgdXNlIHNpbXBsZSBpbnRlcnBvbGF0aW9uIGJldHdlZW4gdHdvIHBvaW50c1xuXG5cdFx0dmFyIGxlbmd0aEJlZm9yZSA9IGFyY0xlbmd0aHNbIGkgXTtcblx0XHR2YXIgbGVuZ3RoQWZ0ZXIgPSBhcmNMZW5ndGhzWyBpICsgMSBdO1xuXG5cdFx0dmFyIHNlZ21lbnRMZW5ndGggPSBsZW5ndGhBZnRlciAtIGxlbmd0aEJlZm9yZTtcblxuXHRcdC8vIGRldGVybWluZSB3aGVyZSB3ZSBhcmUgYmV0d2VlbiB0aGUgJ2JlZm9yZScgYW5kICdhZnRlcicgcG9pbnRzXG5cblx0XHR2YXIgc2VnbWVudEZyYWN0aW9uID0gKCB0YXJnZXRBcmNMZW5ndGggLSBsZW5ndGhCZWZvcmUgKSAvIHNlZ21lbnRMZW5ndGg7XG5cblx0XHQvLyBhZGQgdGhhdCBmcmFjdGlvbmFsIGFtb3VudCB0byB0XG5cblx0XHR2YXIgdCA9ICggaSArIHNlZ21lbnRGcmFjdGlvbiApIC8gKCBpbCAtIDEgKTtcblxuXHRcdHJldHVybiB0O1xuXG5cdH0sXG5cblx0Ly8gUmV0dXJucyBhIHVuaXQgdmVjdG9yIHRhbmdlbnQgYXQgdFxuXHQvLyBJbiBjYXNlIGFueSBzdWIgY3VydmUgZG9lcyBub3QgaW1wbGVtZW50IGl0cyB0YW5nZW50IGRlcml2YXRpb24sXG5cdC8vIDIgcG9pbnRzIGEgc21hbGwgZGVsdGEgYXBhcnQgd2lsbCBiZSB1c2VkIHRvIGZpbmQgaXRzIGdyYWRpZW50XG5cdC8vIHdoaWNoIHNlZW1zIHRvIGdpdmUgYSByZWFzb25hYmxlIGFwcHJveGltYXRpb25cblxuXHRnZXRUYW5nZW50OiBmdW5jdGlvbiAoIHQgKSB7XG5cblx0XHR2YXIgZGVsdGEgPSAwLjAwMDE7XG5cdFx0dmFyIHQxID0gdCAtIGRlbHRhO1xuXHRcdHZhciB0MiA9IHQgKyBkZWx0YTtcblxuXHRcdC8vIENhcHBpbmcgaW4gY2FzZSBvZiBkYW5nZXJcblxuXHRcdGlmICggdDEgPCAwICkgdDEgPSAwO1xuXHRcdGlmICggdDIgPiAxICkgdDIgPSAxO1xuXG5cdFx0dmFyIHB0MSA9IHRoaXMuZ2V0UG9pbnQoIHQxICk7XG5cdFx0dmFyIHB0MiA9IHRoaXMuZ2V0UG9pbnQoIHQyICk7XG5cblx0XHR2YXIgdmVjID0gcHQyLmNsb25lKCkuc3ViKCBwdDEgKTtcblx0XHRyZXR1cm4gdmVjLm5vcm1hbGl6ZSgpO1xuXG5cdH0sXG5cblx0Z2V0VGFuZ2VudEF0OiBmdW5jdGlvbiAoIHUgKSB7XG5cblx0XHR2YXIgdCA9IHRoaXMuZ2V0VXRvVG1hcHBpbmcoIHUgKTtcblx0XHRyZXR1cm4gdGhpcy5nZXRUYW5nZW50KCB0ICk7XG5cblx0fSxcblxuXHRjb21wdXRlRnJlbmV0RnJhbWVzOiBmdW5jdGlvbiAoIHNlZ21lbnRzLCBjbG9zZWQgKSB7XG5cblx0XHQvLyBzZWUgaHR0cDovL3d3dy5jcy5pbmRpYW5hLmVkdS9wdWIvdGVjaHJlcG9ydHMvVFI0MjUucGRmXG5cblx0XHR2YXIgbm9ybWFsID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHZhciB0YW5nZW50cyA9IFtdO1xuXHRcdHZhciBub3JtYWxzID0gW107XG5cdFx0dmFyIGJpbm9ybWFscyA9IFtdO1xuXG5cdFx0dmFyIHZlYyA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIG1hdCA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHR2YXIgaSwgdSwgdGhldGE7XG5cblx0XHQvLyBjb21wdXRlIHRoZSB0YW5nZW50IHZlY3RvcnMgZm9yIGVhY2ggc2VnbWVudCBvbiB0aGUgY3VydmVcblxuXHRcdGZvciAoIGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0XHR1ID0gaSAvIHNlZ21lbnRzO1xuXG5cdFx0XHR0YW5nZW50c1sgaSBdID0gdGhpcy5nZXRUYW5nZW50QXQoIHUgKTtcblx0XHRcdHRhbmdlbnRzWyBpIF0ubm9ybWFsaXplKCk7XG5cblx0XHR9XG5cblx0XHQvLyBzZWxlY3QgYW4gaW5pdGlhbCBub3JtYWwgdmVjdG9yIHBlcnBlbmRpY3VsYXIgdG8gdGhlIGZpcnN0IHRhbmdlbnQgdmVjdG9yLFxuXHRcdC8vIGFuZCBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBtaW5pbXVtIHRhbmdlbnQgeHl6IGNvbXBvbmVudFxuXG5cdFx0bm9ybWFsc1sgMCBdID0gbmV3IFZlY3RvcjMoKTtcblx0XHRiaW5vcm1hbHNbIDAgXSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0dmFyIG1pbiA9IE51bWJlci5NQVhfVkFMVUU7XG5cdFx0dmFyIHR4ID0gTWF0aC5hYnMoIHRhbmdlbnRzWyAwIF0ueCApO1xuXHRcdHZhciB0eSA9IE1hdGguYWJzKCB0YW5nZW50c1sgMCBdLnkgKTtcblx0XHR2YXIgdHogPSBNYXRoLmFicyggdGFuZ2VudHNbIDAgXS56ICk7XG5cblx0XHRpZiAoIHR4IDw9IG1pbiApIHtcblxuXHRcdFx0bWluID0gdHg7XG5cdFx0XHRub3JtYWwuc2V0KCAxLCAwLCAwICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIHR5IDw9IG1pbiApIHtcblxuXHRcdFx0bWluID0gdHk7XG5cdFx0XHRub3JtYWwuc2V0KCAwLCAxLCAwICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIHR6IDw9IG1pbiApIHtcblxuXHRcdFx0bm9ybWFsLnNldCggMCwgMCwgMSApO1xuXG5cdFx0fVxuXG5cdFx0dmVjLmNyb3NzVmVjdG9ycyggdGFuZ2VudHNbIDAgXSwgbm9ybWFsICkubm9ybWFsaXplKCk7XG5cblx0XHRub3JtYWxzWyAwIF0uY3Jvc3NWZWN0b3JzKCB0YW5nZW50c1sgMCBdLCB2ZWMgKTtcblx0XHRiaW5vcm1hbHNbIDAgXS5jcm9zc1ZlY3RvcnMoIHRhbmdlbnRzWyAwIF0sIG5vcm1hbHNbIDAgXSApO1xuXG5cblx0XHQvLyBjb21wdXRlIHRoZSBzbG93bHktdmFyeWluZyBub3JtYWwgYW5kIGJpbm9ybWFsIHZlY3RvcnMgZm9yIGVhY2ggc2VnbWVudCBvbiB0aGUgY3VydmVcblxuXHRcdGZvciAoIGkgPSAxOyBpIDw9IHNlZ21lbnRzOyBpICsrICkge1xuXG5cdFx0XHRub3JtYWxzWyBpIF0gPSBub3JtYWxzWyBpIC0gMSBdLmNsb25lKCk7XG5cblx0XHRcdGJpbm9ybWFsc1sgaSBdID0gYmlub3JtYWxzWyBpIC0gMSBdLmNsb25lKCk7XG5cblx0XHRcdHZlYy5jcm9zc1ZlY3RvcnMoIHRhbmdlbnRzWyBpIC0gMSBdLCB0YW5nZW50c1sgaSBdICk7XG5cblx0XHRcdGlmICggdmVjLmxlbmd0aCgpID4gTnVtYmVyLkVQU0lMT04gKSB7XG5cblx0XHRcdFx0dmVjLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHRcdHRoZXRhID0gTWF0aC5hY29zKCBfTWF0aC5jbGFtcCggdGFuZ2VudHNbIGkgLSAxIF0uZG90KCB0YW5nZW50c1sgaSBdICksIC0gMSwgMSApICk7IC8vIGNsYW1wIGZvciBmbG9hdGluZyBwdCBlcnJvcnNcblxuXHRcdFx0XHRub3JtYWxzWyBpIF0uYXBwbHlNYXRyaXg0KCBtYXQubWFrZVJvdGF0aW9uQXhpcyggdmVjLCB0aGV0YSApICk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ymlub3JtYWxzWyBpIF0uY3Jvc3NWZWN0b3JzKCB0YW5nZW50c1sgaSBdLCBub3JtYWxzWyBpIF0gKTtcblxuXHRcdH1cblxuXHRcdC8vIGlmIHRoZSBjdXJ2ZSBpcyBjbG9zZWQsIHBvc3Rwcm9jZXNzIHRoZSB2ZWN0b3JzIHNvIHRoZSBmaXJzdCBhbmQgbGFzdCBub3JtYWwgdmVjdG9ycyBhcmUgdGhlIHNhbWVcblxuXHRcdGlmICggY2xvc2VkID09PSB0cnVlICkge1xuXG5cdFx0XHR0aGV0YSA9IE1hdGguYWNvcyggX01hdGguY2xhbXAoIG5vcm1hbHNbIDAgXS5kb3QoIG5vcm1hbHNbIHNlZ21lbnRzIF0gKSwgLSAxLCAxICkgKTtcblx0XHRcdHRoZXRhIC89IHNlZ21lbnRzO1xuXG5cdFx0XHRpZiAoIHRhbmdlbnRzWyAwIF0uZG90KCB2ZWMuY3Jvc3NWZWN0b3JzKCBub3JtYWxzWyAwIF0sIG5vcm1hbHNbIHNlZ21lbnRzIF0gKSApID4gMCApIHtcblxuXHRcdFx0XHR0aGV0YSA9IC0gdGhldGE7XG5cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaSA9IDE7IGkgPD0gc2VnbWVudHM7IGkgKysgKSB7XG5cblx0XHRcdFx0Ly8gdHdpc3QgYSBsaXR0bGUuLi5cblx0XHRcdFx0bm9ybWFsc1sgaSBdLmFwcGx5TWF0cml4NCggbWF0Lm1ha2VSb3RhdGlvbkF4aXMoIHRhbmdlbnRzWyBpIF0sIHRoZXRhICogaSApICk7XG5cdFx0XHRcdGJpbm9ybWFsc1sgaSBdLmNyb3NzVmVjdG9ycyggdGFuZ2VudHNbIGkgXSwgbm9ybWFsc1sgaSBdICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHR0YW5nZW50czogdGFuZ2VudHMsXG5cdFx0XHRub3JtYWxzOiBub3JtYWxzLFxuXHRcdFx0Ymlub3JtYWxzOiBiaW5vcm1hbHNcblx0XHR9O1xuXG5cdH1cblxufSApO1xuXG5mdW5jdGlvbiBMaW5lQ3VydmUoIHYxLCB2MiApIHtcblxuXHRDdXJ2ZS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy52MSA9IHYxO1xuXHR0aGlzLnYyID0gdjI7XG5cbn1cblxuTGluZUN1cnZlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuTGluZUN1cnZlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExpbmVDdXJ2ZTtcblxuTGluZUN1cnZlLnByb3RvdHlwZS5pc0xpbmVDdXJ2ZSA9IHRydWU7XG5cbkxpbmVDdXJ2ZS5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAoIHQgKSB7XG5cblx0aWYgKCB0ID09PSAxICkge1xuXG5cdFx0cmV0dXJuIHRoaXMudjIuY2xvbmUoKTtcblxuXHR9XG5cblx0dmFyIHBvaW50ID0gdGhpcy52Mi5jbG9uZSgpLnN1YiggdGhpcy52MSApO1xuXHRwb2ludC5tdWx0aXBseVNjYWxhciggdCApLmFkZCggdGhpcy52MSApO1xuXG5cdHJldHVybiBwb2ludDtcblxufTtcblxuLy8gTGluZSBjdXJ2ZSBpcyBsaW5lYXIsIHNvIHdlIGNhbiBvdmVyd3JpdGUgZGVmYXVsdCBnZXRQb2ludEF0XG5cbkxpbmVDdXJ2ZS5wcm90b3R5cGUuZ2V0UG9pbnRBdCA9IGZ1bmN0aW9uICggdSApIHtcblxuXHRyZXR1cm4gdGhpcy5nZXRQb2ludCggdSApO1xuXG59O1xuXG5MaW5lQ3VydmUucHJvdG90eXBlLmdldFRhbmdlbnQgPSBmdW5jdGlvbiAoIHQgKSB7XG5cblx0dmFyIHRhbmdlbnQgPSB0aGlzLnYyLmNsb25lKCkuc3ViKCB0aGlzLnYxICk7XG5cblx0cmV0dXJuIHRhbmdlbnQubm9ybWFsaXplKCk7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICpcbiAqKi9cblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKlx0Q3VydmVkIFBhdGggLSBhIGN1cnZlIHBhdGggaXMgc2ltcGx5IGEgYXJyYXkgb2YgY29ubmVjdGVkXG4gKiAgY3VydmVzLCBidXQgcmV0YWlucyB0aGUgYXBpIG9mIGEgY3VydmVcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuZnVuY3Rpb24gQ3VydmVQYXRoKCkge1xuXG5cdEN1cnZlLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLmN1cnZlcyA9IFtdO1xuXG5cdHRoaXMuYXV0b0Nsb3NlID0gZmFsc2U7IC8vIEF1dG9tYXRpY2FsbHkgY2xvc2VzIHRoZSBwYXRoXG5cbn1cblxuQ3VydmVQYXRoLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IEN1cnZlUGF0aCxcblxuXHRhZGQ6IGZ1bmN0aW9uICggY3VydmUgKSB7XG5cblx0XHR0aGlzLmN1cnZlcy5wdXNoKCBjdXJ2ZSApO1xuXG5cdH0sXG5cblx0Y2xvc2VQYXRoOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyBBZGQgYSBsaW5lIGN1cnZlIGlmIHN0YXJ0IGFuZCBlbmQgb2YgbGluZXMgYXJlIG5vdCBjb25uZWN0ZWRcblx0XHR2YXIgc3RhcnRQb2ludCA9IHRoaXMuY3VydmVzWyAwIF0uZ2V0UG9pbnQoIDAgKTtcblx0XHR2YXIgZW5kUG9pbnQgPSB0aGlzLmN1cnZlc1sgdGhpcy5jdXJ2ZXMubGVuZ3RoIC0gMSBdLmdldFBvaW50KCAxICk7XG5cblx0XHRpZiAoICEgc3RhcnRQb2ludC5lcXVhbHMoIGVuZFBvaW50ICkgKSB7XG5cblx0XHRcdHRoaXMuY3VydmVzLnB1c2goIG5ldyBMaW5lQ3VydmUoIGVuZFBvaW50LCBzdGFydFBvaW50ICkgKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdC8vIFRvIGdldCBhY2N1cmF0ZSBwb2ludCB3aXRoIHJlZmVyZW5jZSB0b1xuXHQvLyBlbnRpcmUgcGF0aCBkaXN0YW5jZSBhdCB0aW1lIHQsXG5cdC8vIGZvbGxvd2luZyBoYXMgdG8gYmUgZG9uZTpcblxuXHQvLyAxLiBMZW5ndGggb2YgZWFjaCBzdWIgcGF0aCBoYXZlIHRvIGJlIGtub3duXG5cdC8vIDIuIExvY2F0ZSBhbmQgaWRlbnRpZnkgdHlwZSBvZiBjdXJ2ZVxuXHQvLyAzLiBHZXQgdCBmb3IgdGhlIGN1cnZlXG5cdC8vIDQuIFJldHVybiBjdXJ2ZS5nZXRQb2ludEF0KHQnKVxuXG5cdGdldFBvaW50OiBmdW5jdGlvbiAoIHQgKSB7XG5cblx0XHR2YXIgZCA9IHQgKiB0aGlzLmdldExlbmd0aCgpO1xuXHRcdHZhciBjdXJ2ZUxlbmd0aHMgPSB0aGlzLmdldEN1cnZlTGVuZ3RocygpO1xuXHRcdHZhciBpID0gMDtcblxuXHRcdC8vIFRvIHRoaW5rIGFib3V0IGJvdW5kYXJpZXMgcG9pbnRzLlxuXG5cdFx0d2hpbGUgKCBpIDwgY3VydmVMZW5ndGhzLmxlbmd0aCApIHtcblxuXHRcdFx0aWYgKCBjdXJ2ZUxlbmd0aHNbIGkgXSA+PSBkICkge1xuXG5cdFx0XHRcdHZhciBkaWZmID0gY3VydmVMZW5ndGhzWyBpIF0gLSBkO1xuXHRcdFx0XHR2YXIgY3VydmUgPSB0aGlzLmN1cnZlc1sgaSBdO1xuXG5cdFx0XHRcdHZhciBzZWdtZW50TGVuZ3RoID0gY3VydmUuZ2V0TGVuZ3RoKCk7XG5cdFx0XHRcdHZhciB1ID0gc2VnbWVudExlbmd0aCA9PT0gMCA/IDAgOiAxIC0gZGlmZiAvIHNlZ21lbnRMZW5ndGg7XG5cblx0XHRcdFx0cmV0dXJuIGN1cnZlLmdldFBvaW50QXQoIHUgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRpICsrO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cblx0XHQvLyBsb29wIHdoZXJlIHN1bSAhPSAwLCBzdW0gPiBkICwgc3VtKzEgPGRcblxuXHR9LFxuXG5cdC8vIFdlIGNhbm5vdCB1c2UgdGhlIGRlZmF1bHQgVEhSRUUuQ3VydmUgZ2V0UG9pbnQoKSB3aXRoIGdldExlbmd0aCgpIGJlY2F1c2UgaW5cblx0Ly8gVEhSRUUuQ3VydmUsIGdldExlbmd0aCgpIGRlcGVuZHMgb24gZ2V0UG9pbnQoKSBidXQgaW4gVEhSRUUuQ3VydmVQYXRoXG5cdC8vIGdldFBvaW50KCkgZGVwZW5kcyBvbiBnZXRMZW5ndGhcblxuXHRnZXRMZW5ndGg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBsZW5zID0gdGhpcy5nZXRDdXJ2ZUxlbmd0aHMoKTtcblx0XHRyZXR1cm4gbGVuc1sgbGVucy5sZW5ndGggLSAxIF07XG5cblx0fSxcblxuXHQvLyBjYWNoZUxlbmd0aHMgbXVzdCBiZSByZWNhbGN1bGF0ZWQuXG5cdHVwZGF0ZUFyY0xlbmd0aHM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMubmVlZHNVcGRhdGUgPSB0cnVlO1xuXHRcdHRoaXMuY2FjaGVMZW5ndGhzID0gbnVsbDtcblx0XHR0aGlzLmdldEN1cnZlTGVuZ3RocygpO1xuXG5cdH0sXG5cblx0Ly8gQ29tcHV0ZSBsZW5ndGhzIGFuZCBjYWNoZSB0aGVtXG5cdC8vIFdlIGNhbm5vdCBvdmVyd3JpdGUgZ2V0TGVuZ3RocygpIGJlY2F1c2UgVXRvVCBtYXBwaW5nIHVzZXMgaXQuXG5cblx0Z2V0Q3VydmVMZW5ndGhzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyBXZSB1c2UgY2FjaGUgdmFsdWVzIGlmIGN1cnZlcyBhbmQgY2FjaGUgYXJyYXkgYXJlIHNhbWUgbGVuZ3RoXG5cblx0XHRpZiAoIHRoaXMuY2FjaGVMZW5ndGhzICYmIHRoaXMuY2FjaGVMZW5ndGhzLmxlbmd0aCA9PT0gdGhpcy5jdXJ2ZXMubGVuZ3RoICkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5jYWNoZUxlbmd0aHM7XG5cblx0XHR9XG5cblx0XHQvLyBHZXQgbGVuZ3RoIG9mIHN1Yi1jdXJ2ZVxuXHRcdC8vIFB1c2ggc3VtcyBpbnRvIGNhY2hlZCBhcnJheVxuXG5cdFx0dmFyIGxlbmd0aHMgPSBbXSwgc3VtcyA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSB0aGlzLmN1cnZlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRzdW1zICs9IHRoaXMuY3VydmVzWyBpIF0uZ2V0TGVuZ3RoKCk7XG5cdFx0XHRsZW5ndGhzLnB1c2goIHN1bXMgKTtcblxuXHRcdH1cblxuXHRcdHRoaXMuY2FjaGVMZW5ndGhzID0gbGVuZ3RocztcblxuXHRcdHJldHVybiBsZW5ndGhzO1xuXG5cdH0sXG5cblx0Z2V0U3BhY2VkUG9pbnRzOiBmdW5jdGlvbiAoIGRpdmlzaW9ucyApIHtcblxuXHRcdGlmICggZGl2aXNpb25zID09PSB1bmRlZmluZWQgKSBkaXZpc2lvbnMgPSA0MDtcblxuXHRcdHZhciBwb2ludHMgPSBbXTtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8PSBkaXZpc2lvbnM7IGkgKysgKSB7XG5cblx0XHRcdHBvaW50cy5wdXNoKCB0aGlzLmdldFBvaW50KCBpIC8gZGl2aXNpb25zICkgKTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5hdXRvQ2xvc2UgKSB7XG5cblx0XHRcdHBvaW50cy5wdXNoKCBwb2ludHNbIDAgXSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBvaW50cztcblxuXHR9LFxuXG5cdGdldFBvaW50czogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHRkaXZpc2lvbnMgPSBkaXZpc2lvbnMgfHwgMTI7XG5cblx0XHR2YXIgcG9pbnRzID0gW10sIGxhc3Q7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGN1cnZlcyA9IHRoaXMuY3VydmVzOyBpIDwgY3VydmVzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGN1cnZlID0gY3VydmVzWyBpIF07XG5cdFx0XHR2YXIgcmVzb2x1dGlvbiA9IChjdXJ2ZSAmJiBjdXJ2ZS5pc0VsbGlwc2VDdXJ2ZSkgPyBkaXZpc2lvbnMgKiAyXG5cdFx0XHRcdDogKGN1cnZlICYmIGN1cnZlLmlzTGluZUN1cnZlKSA/IDFcblx0XHRcdFx0OiAoY3VydmUgJiYgY3VydmUuaXNTcGxpbmVDdXJ2ZSkgPyBkaXZpc2lvbnMgKiBjdXJ2ZS5wb2ludHMubGVuZ3RoXG5cdFx0XHRcdDogZGl2aXNpb25zO1xuXG5cdFx0XHR2YXIgcHRzID0gY3VydmUuZ2V0UG9pbnRzKCByZXNvbHV0aW9uICk7XG5cblx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IHB0cy5sZW5ndGg7IGorKyApIHtcblxuXHRcdFx0XHR2YXIgcG9pbnQgPSBwdHNbIGogXTtcblxuXHRcdFx0XHRpZiAoIGxhc3QgJiYgbGFzdC5lcXVhbHMoIHBvaW50ICkgKSBjb250aW51ZTsgLy8gZW5zdXJlcyBubyBjb25zZWN1dGl2ZSBwb2ludHMgYXJlIGR1cGxpY2F0ZXNcblxuXHRcdFx0XHRwb2ludHMucHVzaCggcG9pbnQgKTtcblx0XHRcdFx0bGFzdCA9IHBvaW50O1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuYXV0b0Nsb3NlICYmIHBvaW50cy5sZW5ndGggPiAxICYmICFwb2ludHNbIHBvaW50cy5sZW5ndGggLSAxIF0uZXF1YWxzKCBwb2ludHNbIDAgXSApICkge1xuXG5cdFx0XHRwb2ludHMucHVzaCggcG9pbnRzWyAwIF0gKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiBwb2ludHM7XG5cblx0fSxcblxuXHQvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblx0ICpcdENyZWF0ZSBHZW9tZXRyaWVzIEhlbHBlcnNcblx0ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cdC8vLyBHZW5lcmF0ZSBnZW9tZXRyeSBmcm9tIHBhdGggcG9pbnRzIChmb3IgTGluZSBvciBQb2ludHMgb2JqZWN0cylcblxuXHRjcmVhdGVQb2ludHNHZW9tZXRyeTogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHR2YXIgcHRzID0gdGhpcy5nZXRQb2ludHMoIGRpdmlzaW9ucyApO1xuXHRcdHJldHVybiB0aGlzLmNyZWF0ZUdlb21ldHJ5KCBwdHMgKTtcblxuXHR9LFxuXG5cdC8vIEdlbmVyYXRlIGdlb21ldHJ5IGZyb20gZXF1aWRpc3RhbnQgc2FtcGxpbmcgYWxvbmcgdGhlIHBhdGhcblxuXHRjcmVhdGVTcGFjZWRQb2ludHNHZW9tZXRyeTogZnVuY3Rpb24gKCBkaXZpc2lvbnMgKSB7XG5cblx0XHR2YXIgcHRzID0gdGhpcy5nZXRTcGFjZWRQb2ludHMoIGRpdmlzaW9ucyApO1xuXHRcdHJldHVybiB0aGlzLmNyZWF0ZUdlb21ldHJ5KCBwdHMgKTtcblxuXHR9LFxuXG5cdGNyZWF0ZUdlb21ldHJ5OiBmdW5jdGlvbiAoIHBvaW50cyApIHtcblxuXHRcdHZhciBnZW9tZXRyeSA9IG5ldyBHZW9tZXRyeSgpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gcG9pbnRzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHZhciBwb2ludCA9IHBvaW50c1sgaSBdO1xuXHRcdFx0Z2VvbWV0cnkudmVydGljZXMucHVzaCggbmV3IFZlY3RvcjMoIHBvaW50LngsIHBvaW50LnksIHBvaW50LnogfHwgMCApICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gZ2VvbWV0cnk7XG5cblx0fVxuXG59ICk7XG5cbmZ1bmN0aW9uIEVsbGlwc2VDdXJ2ZSggYVgsIGFZLCB4UmFkaXVzLCB5UmFkaXVzLCBhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlLCBhUm90YXRpb24gKSB7XG5cblx0Q3VydmUuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMuYVggPSBhWDtcblx0dGhpcy5hWSA9IGFZO1xuXG5cdHRoaXMueFJhZGl1cyA9IHhSYWRpdXM7XG5cdHRoaXMueVJhZGl1cyA9IHlSYWRpdXM7XG5cblx0dGhpcy5hU3RhcnRBbmdsZSA9IGFTdGFydEFuZ2xlO1xuXHR0aGlzLmFFbmRBbmdsZSA9IGFFbmRBbmdsZTtcblxuXHR0aGlzLmFDbG9ja3dpc2UgPSBhQ2xvY2t3aXNlO1xuXG5cdHRoaXMuYVJvdGF0aW9uID0gYVJvdGF0aW9uIHx8IDA7XG5cbn1cblxuRWxsaXBzZUN1cnZlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuRWxsaXBzZUN1cnZlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEVsbGlwc2VDdXJ2ZTtcblxuRWxsaXBzZUN1cnZlLnByb3RvdHlwZS5pc0VsbGlwc2VDdXJ2ZSA9IHRydWU7XG5cbkVsbGlwc2VDdXJ2ZS5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAoIHQgKSB7XG5cblx0dmFyIHR3b1BpID0gTWF0aC5QSSAqIDI7XG5cdHZhciBkZWx0YUFuZ2xlID0gdGhpcy5hRW5kQW5nbGUgLSB0aGlzLmFTdGFydEFuZ2xlO1xuXHR2YXIgc2FtZVBvaW50cyA9IE1hdGguYWJzKCBkZWx0YUFuZ2xlICkgPCBOdW1iZXIuRVBTSUxPTjtcblxuXHQvLyBlbnN1cmVzIHRoYXQgZGVsdGFBbmdsZSBpcyAwIC4uIDIgUElcblx0d2hpbGUgKCBkZWx0YUFuZ2xlIDwgMCApIGRlbHRhQW5nbGUgKz0gdHdvUGk7XG5cdHdoaWxlICggZGVsdGFBbmdsZSA+IHR3b1BpICkgZGVsdGFBbmdsZSAtPSB0d29QaTtcblxuXHRpZiAoIGRlbHRhQW5nbGUgPCBOdW1iZXIuRVBTSUxPTiApIHtcblxuXHRcdGlmICggc2FtZVBvaW50cyApIHtcblxuXHRcdFx0ZGVsdGFBbmdsZSA9IDA7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRkZWx0YUFuZ2xlID0gdHdvUGk7XG5cblx0XHR9XG5cblx0fVxuXG5cdGlmICggdGhpcy5hQ2xvY2t3aXNlID09PSB0cnVlICYmICEgc2FtZVBvaW50cyApIHtcblxuXHRcdGlmICggZGVsdGFBbmdsZSA9PT0gdHdvUGkgKSB7XG5cblx0XHRcdGRlbHRhQW5nbGUgPSAtIHR3b1BpO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0ZGVsdGFBbmdsZSA9IGRlbHRhQW5nbGUgLSB0d29QaTtcblxuXHRcdH1cblxuXHR9XG5cblx0dmFyIGFuZ2xlID0gdGhpcy5hU3RhcnRBbmdsZSArIHQgKiBkZWx0YUFuZ2xlO1xuXHR2YXIgeCA9IHRoaXMuYVggKyB0aGlzLnhSYWRpdXMgKiBNYXRoLmNvcyggYW5nbGUgKTtcblx0dmFyIHkgPSB0aGlzLmFZICsgdGhpcy55UmFkaXVzICogTWF0aC5zaW4oIGFuZ2xlICk7XG5cblx0aWYgKCB0aGlzLmFSb3RhdGlvbiAhPT0gMCApIHtcblxuXHRcdHZhciBjb3MgPSBNYXRoLmNvcyggdGhpcy5hUm90YXRpb24gKTtcblx0XHR2YXIgc2luID0gTWF0aC5zaW4oIHRoaXMuYVJvdGF0aW9uICk7XG5cblx0XHR2YXIgdHggPSB4IC0gdGhpcy5hWDtcblx0XHR2YXIgdHkgPSB5IC0gdGhpcy5hWTtcblxuXHRcdC8vIFJvdGF0ZSB0aGUgcG9pbnQgYWJvdXQgdGhlIGNlbnRlciBvZiB0aGUgZWxsaXBzZS5cblx0XHR4ID0gdHggKiBjb3MgLSB0eSAqIHNpbiArIHRoaXMuYVg7XG5cdFx0eSA9IHR4ICogc2luICsgdHkgKiBjb3MgKyB0aGlzLmFZO1xuXG5cdH1cblxuXHRyZXR1cm4gbmV3IFZlY3RvcjIoIHgsIHkgKTtcblxufTtcblxuZnVuY3Rpb24gU3BsaW5lQ3VydmUoIHBvaW50cyAvKiBhcnJheSBvZiBWZWN0b3IyICovICkge1xuXG5cdEN1cnZlLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnBvaW50cyA9ICggcG9pbnRzID09PSB1bmRlZmluZWQgKSA/IFtdIDogcG9pbnRzO1xuXG59XG5cblNwbGluZUN1cnZlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuU3BsaW5lQ3VydmUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU3BsaW5lQ3VydmU7XG5cblNwbGluZUN1cnZlLnByb3RvdHlwZS5pc1NwbGluZUN1cnZlID0gdHJ1ZTtcblxuU3BsaW5lQ3VydmUucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKCB0ICkge1xuXG5cdHZhciBwb2ludHMgPSB0aGlzLnBvaW50cztcblx0dmFyIHBvaW50ID0gKCBwb2ludHMubGVuZ3RoIC0gMSApICogdDtcblxuXHR2YXIgaW50UG9pbnQgPSBNYXRoLmZsb29yKCBwb2ludCApO1xuXHR2YXIgd2VpZ2h0ID0gcG9pbnQgLSBpbnRQb2ludDtcblxuXHR2YXIgcG9pbnQwID0gcG9pbnRzWyBpbnRQb2ludCA9PT0gMCA/IGludFBvaW50IDogaW50UG9pbnQgLSAxIF07XG5cdHZhciBwb2ludDEgPSBwb2ludHNbIGludFBvaW50IF07XG5cdHZhciBwb2ludDIgPSBwb2ludHNbIGludFBvaW50ID4gcG9pbnRzLmxlbmd0aCAtIDIgPyBwb2ludHMubGVuZ3RoIC0gMSA6IGludFBvaW50ICsgMSBdO1xuXHR2YXIgcG9pbnQzID0gcG9pbnRzWyBpbnRQb2ludCA+IHBvaW50cy5sZW5ndGggLSAzID8gcG9pbnRzLmxlbmd0aCAtIDEgOiBpbnRQb2ludCArIDIgXTtcblxuXHRyZXR1cm4gbmV3IFZlY3RvcjIoXG5cdFx0Q2F0bXVsbFJvbSggd2VpZ2h0LCBwb2ludDAueCwgcG9pbnQxLngsIHBvaW50Mi54LCBwb2ludDMueCApLFxuXHRcdENhdG11bGxSb20oIHdlaWdodCwgcG9pbnQwLnksIHBvaW50MS55LCBwb2ludDIueSwgcG9pbnQzLnkgKVxuXHQpO1xuXG59O1xuXG5mdW5jdGlvbiBDdWJpY0JlemllckN1cnZlKCB2MCwgdjEsIHYyLCB2MyApIHtcblxuXHRDdXJ2ZS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy52MCA9IHYwO1xuXHR0aGlzLnYxID0gdjE7XG5cdHRoaXMudjIgPSB2Mjtcblx0dGhpcy52MyA9IHYzO1xuXG59XG5cbkN1YmljQmV6aWVyQ3VydmUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQ3VydmUucHJvdG90eXBlICk7XG5DdWJpY0JlemllckN1cnZlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEN1YmljQmV6aWVyQ3VydmU7XG5cbkN1YmljQmV6aWVyQ3VydmUucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKCB0ICkge1xuXG5cdHZhciB2MCA9IHRoaXMudjAsIHYxID0gdGhpcy52MSwgdjIgPSB0aGlzLnYyLCB2MyA9IHRoaXMudjM7XG5cblx0cmV0dXJuIG5ldyBWZWN0b3IyKFxuXHRcdEN1YmljQmV6aWVyKCB0LCB2MC54LCB2MS54LCB2Mi54LCB2My54ICksXG5cdFx0Q3ViaWNCZXppZXIoIHQsIHYwLnksIHYxLnksIHYyLnksIHYzLnkgKVxuXHQpO1xuXG59O1xuXG5mdW5jdGlvbiBRdWFkcmF0aWNCZXppZXJDdXJ2ZSggdjAsIHYxLCB2MiApIHtcblxuXHRDdXJ2ZS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy52MCA9IHYwO1xuXHR0aGlzLnYxID0gdjE7XG5cdHRoaXMudjIgPSB2MjtcblxufVxuXG5RdWFkcmF0aWNCZXppZXJDdXJ2ZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBDdXJ2ZS5wcm90b3R5cGUgKTtcblF1YWRyYXRpY0JlemllckN1cnZlLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFF1YWRyYXRpY0JlemllckN1cnZlO1xuXG5RdWFkcmF0aWNCZXppZXJDdXJ2ZS5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAoIHQgKSB7XG5cblx0dmFyIHYwID0gdGhpcy52MCwgdjEgPSB0aGlzLnYxLCB2MiA9IHRoaXMudjI7XG5cblx0cmV0dXJuIG5ldyBWZWN0b3IyKFxuXHRcdFF1YWRyYXRpY0JlemllciggdCwgdjAueCwgdjEueCwgdjIueCApLFxuXHRcdFF1YWRyYXRpY0JlemllciggdCwgdjAueSwgdjEueSwgdjIueSApXG5cdCk7XG5cbn07XG5cbnZhciBQYXRoUHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggQ3VydmVQYXRoLnByb3RvdHlwZSApLCB7XG5cblx0ZnJvbVBvaW50czogZnVuY3Rpb24gKCB2ZWN0b3JzICkge1xuXG5cdFx0dGhpcy5tb3ZlVG8oIHZlY3RvcnNbIDAgXS54LCB2ZWN0b3JzWyAwIF0ueSApO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAxLCBsID0gdmVjdG9ycy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLmxpbmVUbyggdmVjdG9yc1sgaSBdLngsIHZlY3RvcnNbIGkgXS55ICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRtb3ZlVG86IGZ1bmN0aW9uICggeCwgeSApIHtcblxuXHRcdHRoaXMuY3VycmVudFBvaW50LnNldCggeCwgeSApOyAvLyBUT0RPIGNvbnNpZGVyIHJlZmVyZW5jaW5nIHZlY3RvcnMgaW5zdGVhZCBvZiBjb3B5aW5nP1xuXG5cdH0sXG5cblx0bGluZVRvOiBmdW5jdGlvbiAoIHgsIHkgKSB7XG5cblx0XHR2YXIgY3VydmUgPSBuZXcgTGluZUN1cnZlKCB0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLCBuZXcgVmVjdG9yMiggeCwgeSApICk7XG5cdFx0dGhpcy5jdXJ2ZXMucHVzaCggY3VydmUgKTtcblxuXHRcdHRoaXMuY3VycmVudFBvaW50LnNldCggeCwgeSApO1xuXG5cdH0sXG5cblx0cXVhZHJhdGljQ3VydmVUbzogZnVuY3Rpb24gKCBhQ1B4LCBhQ1B5LCBhWCwgYVkgKSB7XG5cblx0XHR2YXIgY3VydmUgPSBuZXcgUXVhZHJhdGljQmV6aWVyQ3VydmUoXG5cdFx0XHR0aGlzLmN1cnJlbnRQb2ludC5jbG9uZSgpLFxuXHRcdFx0bmV3IFZlY3RvcjIoIGFDUHgsIGFDUHkgKSxcblx0XHRcdG5ldyBWZWN0b3IyKCBhWCwgYVkgKVxuXHRcdCk7XG5cblx0XHR0aGlzLmN1cnZlcy5wdXNoKCBjdXJ2ZSApO1xuXG5cdFx0dGhpcy5jdXJyZW50UG9pbnQuc2V0KCBhWCwgYVkgKTtcblxuXHR9LFxuXG5cdGJlemllckN1cnZlVG86IGZ1bmN0aW9uICggYUNQMXgsIGFDUDF5LCBhQ1AyeCwgYUNQMnksIGFYLCBhWSApIHtcblxuXHRcdHZhciBjdXJ2ZSA9IG5ldyBDdWJpY0JlemllckN1cnZlKFxuXHRcdFx0dGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSxcblx0XHRcdG5ldyBWZWN0b3IyKCBhQ1AxeCwgYUNQMXkgKSxcblx0XHRcdG5ldyBWZWN0b3IyKCBhQ1AyeCwgYUNQMnkgKSxcblx0XHRcdG5ldyBWZWN0b3IyKCBhWCwgYVkgKVxuXHRcdCk7XG5cblx0XHR0aGlzLmN1cnZlcy5wdXNoKCBjdXJ2ZSApO1xuXG5cdFx0dGhpcy5jdXJyZW50UG9pbnQuc2V0KCBhWCwgYVkgKTtcblxuXHR9LFxuXG5cdHNwbGluZVRocnU6IGZ1bmN0aW9uICggcHRzIC8qQXJyYXkgb2YgVmVjdG9yKi8gKSB7XG5cblx0XHR2YXIgbnB0cyA9IFsgdGhpcy5jdXJyZW50UG9pbnQuY2xvbmUoKSBdLmNvbmNhdCggcHRzICk7XG5cblx0XHR2YXIgY3VydmUgPSBuZXcgU3BsaW5lQ3VydmUoIG5wdHMgKTtcblx0XHR0aGlzLmN1cnZlcy5wdXNoKCBjdXJ2ZSApO1xuXG5cdFx0dGhpcy5jdXJyZW50UG9pbnQuY29weSggcHRzWyBwdHMubGVuZ3RoIC0gMSBdICk7XG5cblx0fSxcblxuXHRhcmM6IGZ1bmN0aW9uICggYVgsIGFZLCBhUmFkaXVzLCBhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlICkge1xuXG5cdFx0dmFyIHgwID0gdGhpcy5jdXJyZW50UG9pbnQueDtcblx0XHR2YXIgeTAgPSB0aGlzLmN1cnJlbnRQb2ludC55O1xuXG5cdFx0dGhpcy5hYnNhcmMoIGFYICsgeDAsIGFZICsgeTAsIGFSYWRpdXMsXG5cdFx0XHRhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlICk7XG5cblx0fSxcblxuXHRhYnNhcmM6IGZ1bmN0aW9uICggYVgsIGFZLCBhUmFkaXVzLCBhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlICkge1xuXG5cdFx0dGhpcy5hYnNlbGxpcHNlKCBhWCwgYVksIGFSYWRpdXMsIGFSYWRpdXMsIGFTdGFydEFuZ2xlLCBhRW5kQW5nbGUsIGFDbG9ja3dpc2UgKTtcblxuXHR9LFxuXG5cdGVsbGlwc2U6IGZ1bmN0aW9uICggYVgsIGFZLCB4UmFkaXVzLCB5UmFkaXVzLCBhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlLCBhUm90YXRpb24gKSB7XG5cblx0XHR2YXIgeDAgPSB0aGlzLmN1cnJlbnRQb2ludC54O1xuXHRcdHZhciB5MCA9IHRoaXMuY3VycmVudFBvaW50Lnk7XG5cblx0XHR0aGlzLmFic2VsbGlwc2UoIGFYICsgeDAsIGFZICsgeTAsIHhSYWRpdXMsIHlSYWRpdXMsIGFTdGFydEFuZ2xlLCBhRW5kQW5nbGUsIGFDbG9ja3dpc2UsIGFSb3RhdGlvbiApO1xuXG5cdH0sXG5cblx0YWJzZWxsaXBzZTogZnVuY3Rpb24gKCBhWCwgYVksIHhSYWRpdXMsIHlSYWRpdXMsIGFTdGFydEFuZ2xlLCBhRW5kQW5nbGUsIGFDbG9ja3dpc2UsIGFSb3RhdGlvbiApIHtcblxuXHRcdHZhciBjdXJ2ZSA9IG5ldyBFbGxpcHNlQ3VydmUoIGFYLCBhWSwgeFJhZGl1cywgeVJhZGl1cywgYVN0YXJ0QW5nbGUsIGFFbmRBbmdsZSwgYUNsb2Nrd2lzZSwgYVJvdGF0aW9uICk7XG5cblx0XHRpZiAoIHRoaXMuY3VydmVzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdC8vIGlmIGEgcHJldmlvdXMgY3VydmUgaXMgcHJlc2VudCwgYXR0ZW1wdCB0byBqb2luXG5cdFx0XHR2YXIgZmlyc3RQb2ludCA9IGN1cnZlLmdldFBvaW50KCAwICk7XG5cblx0XHRcdGlmICggISBmaXJzdFBvaW50LmVxdWFscyggdGhpcy5jdXJyZW50UG9pbnQgKSApIHtcblxuXHRcdFx0XHR0aGlzLmxpbmVUbyggZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnkgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dGhpcy5jdXJ2ZXMucHVzaCggY3VydmUgKTtcblxuXHRcdHZhciBsYXN0UG9pbnQgPSBjdXJ2ZS5nZXRQb2ludCggMSApO1xuXHRcdHRoaXMuY3VycmVudFBvaW50LmNvcHkoIGxhc3RQb2ludCApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3Igeno4NSAvIGh0dHA6Ly93d3cubGFiNGdhbWVzLm5ldC96ejg1L2Jsb2dcbiAqIENyZWF0ZXMgZnJlZSBmb3JtIDJkIHBhdGggdXNpbmcgc2VyaWVzIG9mIHBvaW50cywgbGluZXMgb3IgY3VydmVzLlxuICoqL1xuXG5mdW5jdGlvbiBQYXRoKCBwb2ludHMgKSB7XG5cblx0Q3VydmVQYXRoLmNhbGwoIHRoaXMgKTtcblx0dGhpcy5jdXJyZW50UG9pbnQgPSBuZXcgVmVjdG9yMigpO1xuXG5cdGlmICggcG9pbnRzICkge1xuXG5cdFx0dGhpcy5mcm9tUG9pbnRzKCBwb2ludHMgKTtcblxuXHR9XG5cbn1cblxuUGF0aC5wcm90b3R5cGUgPSBQYXRoUHJvdG90eXBlO1xuUGF0aFByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBhdGg7XG5cbi8qKlxuICogQGF1dGhvciB6ejg1IC8gaHR0cDovL3d3dy5sYWI0Z2FtZXMubmV0L3p6ODUvYmxvZ1xuICogRGVmaW5lcyBhIDJkIHNoYXBlIHBsYW5lIHVzaW5nIHBhdGhzLlxuICoqL1xuXG4vLyBTVEVQIDEgQ3JlYXRlIGEgcGF0aC5cbi8vIFNURVAgMiBUdXJuIHBhdGggaW50byBzaGFwZS5cbi8vIFNURVAgMyBFeHRydWRlR2VvbWV0cnkgdGFrZXMgaW4gU2hhcGUvU2hhcGVzXG4vLyBTVEVQIDNhIC0gRXh0cmFjdCBwb2ludHMgZnJvbSBlYWNoIHNoYXBlLCB0dXJuIHRvIHZlcnRpY2VzXG4vLyBTVEVQIDNiIC0gVHJpYW5ndWxhdGUgZWFjaCBzaGFwZSwgYWRkIGZhY2VzLlxuXG5mdW5jdGlvbiBTaGFwZSgpIHtcblxuXHRQYXRoLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblxuXHR0aGlzLmhvbGVzID0gW107XG5cbn1cblxuU2hhcGUucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggUGF0aFByb3RvdHlwZSApLCB7XG5cblx0Y29uc3RydWN0b3I6IFNoYXBlLFxuXG5cdGdldFBvaW50c0hvbGVzOiBmdW5jdGlvbiAoIGRpdmlzaW9ucyApIHtcblxuXHRcdHZhciBob2xlc1B0cyA9IFtdO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gdGhpcy5ob2xlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRob2xlc1B0c1sgaSBdID0gdGhpcy5ob2xlc1sgaSBdLmdldFBvaW50cyggZGl2aXNpb25zICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gaG9sZXNQdHM7XG5cblx0fSxcblxuXHQvLyBHZXQgcG9pbnRzIG9mIHNoYXBlIGFuZCBob2xlcyAoa2V5cG9pbnRzIGJhc2VkIG9uIHNlZ21lbnRzIHBhcmFtZXRlcilcblxuXHRleHRyYWN0QWxsUG9pbnRzOiBmdW5jdGlvbiAoIGRpdmlzaW9ucyApIHtcblxuXHRcdHJldHVybiB7XG5cblx0XHRcdHNoYXBlOiB0aGlzLmdldFBvaW50cyggZGl2aXNpb25zICksXG5cdFx0XHRob2xlczogdGhpcy5nZXRQb2ludHNIb2xlcyggZGl2aXNpb25zIClcblxuXHRcdH07XG5cblx0fSxcblxuXHRleHRyYWN0UG9pbnRzOiBmdW5jdGlvbiAoIGRpdmlzaW9ucyApIHtcblxuXHRcdHJldHVybiB0aGlzLmV4dHJhY3RBbGxQb2ludHMoIGRpdmlzaW9ucyApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3Igeno4NSAvIGh0dHA6Ly93d3cubGFiNGdhbWVzLm5ldC96ejg1L2Jsb2dcbiAqIG1pbmltYWwgY2xhc3MgZm9yIHByb3hpbmcgZnVuY3Rpb25zIHRvIFBhdGguIFJlcGxhY2VzIG9sZCBcImV4dHJhY3RTdWJwYXRocygpXCJcbiAqKi9cblxuZnVuY3Rpb24gU2hhcGVQYXRoKCkge1xuXG5cdHRoaXMuc3ViUGF0aHMgPSBbXTtcblx0dGhpcy5jdXJyZW50UGF0aCA9IG51bGw7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggU2hhcGVQYXRoLnByb3RvdHlwZSwge1xuXG5cdG1vdmVUbzogZnVuY3Rpb24gKCB4LCB5ICkge1xuXG5cdFx0dGhpcy5jdXJyZW50UGF0aCA9IG5ldyBQYXRoKCk7XG5cdFx0dGhpcy5zdWJQYXRocy5wdXNoKCB0aGlzLmN1cnJlbnRQYXRoICk7XG5cdFx0dGhpcy5jdXJyZW50UGF0aC5tb3ZlVG8oIHgsIHkgKTtcblxuXHR9LFxuXG5cdGxpbmVUbzogZnVuY3Rpb24gKCB4LCB5ICkge1xuXG5cdFx0dGhpcy5jdXJyZW50UGF0aC5saW5lVG8oIHgsIHkgKTtcblxuXHR9LFxuXG5cdHF1YWRyYXRpY0N1cnZlVG86IGZ1bmN0aW9uICggYUNQeCwgYUNQeSwgYVgsIGFZICkge1xuXG5cdFx0dGhpcy5jdXJyZW50UGF0aC5xdWFkcmF0aWNDdXJ2ZVRvKCBhQ1B4LCBhQ1B5LCBhWCwgYVkgKTtcblxuXHR9LFxuXG5cdGJlemllckN1cnZlVG86IGZ1bmN0aW9uICggYUNQMXgsIGFDUDF5LCBhQ1AyeCwgYUNQMnksIGFYLCBhWSApIHtcblxuXHRcdHRoaXMuY3VycmVudFBhdGguYmV6aWVyQ3VydmVUbyggYUNQMXgsIGFDUDF5LCBhQ1AyeCwgYUNQMnksIGFYLCBhWSApO1xuXG5cdH0sXG5cblx0c3BsaW5lVGhydTogZnVuY3Rpb24gKCBwdHMgKSB7XG5cblx0XHR0aGlzLmN1cnJlbnRQYXRoLnNwbGluZVRocnUoIHB0cyApO1xuXG5cdH0sXG5cblx0dG9TaGFwZXM6IGZ1bmN0aW9uICggaXNDQ1csIG5vSG9sZXMgKSB7XG5cblx0XHRmdW5jdGlvbiB0b1NoYXBlc05vSG9sZXMoIGluU3VicGF0aHMgKSB7XG5cblx0XHRcdHZhciBzaGFwZXMgPSBbXTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gaW5TdWJwYXRocy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRcdHZhciB0bXBQYXRoID0gaW5TdWJwYXRoc1sgaSBdO1xuXG5cdFx0XHRcdHZhciB0bXBTaGFwZSA9IG5ldyBTaGFwZSgpO1xuXHRcdFx0XHR0bXBTaGFwZS5jdXJ2ZXMgPSB0bXBQYXRoLmN1cnZlcztcblxuXHRcdFx0XHRzaGFwZXMucHVzaCggdG1wU2hhcGUgKTtcblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2hhcGVzO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gaXNQb2ludEluc2lkZVBvbHlnb24oIGluUHQsIGluUG9seWdvbiApIHtcblxuXHRcdFx0dmFyIHBvbHlMZW4gPSBpblBvbHlnb24ubGVuZ3RoO1xuXG5cdFx0XHQvLyBpblB0IG9uIHBvbHlnb24gY29udG91ciA9PiBpbW1lZGlhdGUgc3VjY2VzcyAgICBvclxuXHRcdFx0Ly8gdG9nZ2xpbmcgb2YgaW5zaWRlL291dHNpZGUgYXQgZXZlcnkgc2luZ2xlISBpbnRlcnNlY3Rpb24gcG9pbnQgb2YgYW4gZWRnZVxuXHRcdFx0Ly8gIHdpdGggdGhlIGhvcml6b250YWwgbGluZSB0aHJvdWdoIGluUHQsIGxlZnQgb2YgaW5QdFxuXHRcdFx0Ly8gIG5vdCBjb3VudGluZyBsb3dlclkgZW5kcG9pbnRzIG9mIGVkZ2VzIGFuZCB3aG9sZSBlZGdlcyBvbiB0aGF0IGxpbmVcblx0XHRcdHZhciBpbnNpZGUgPSBmYWxzZTtcblx0XHRcdGZvciAoIHZhciBwID0gcG9seUxlbiAtIDEsIHEgPSAwOyBxIDwgcG9seUxlbjsgcCA9IHEgKysgKSB7XG5cblx0XHRcdFx0dmFyIGVkZ2VMb3dQdCAgPSBpblBvbHlnb25bIHAgXTtcblx0XHRcdFx0dmFyIGVkZ2VIaWdoUHQgPSBpblBvbHlnb25bIHEgXTtcblxuXHRcdFx0XHR2YXIgZWRnZUR4ID0gZWRnZUhpZ2hQdC54IC0gZWRnZUxvd1B0Lng7XG5cdFx0XHRcdHZhciBlZGdlRHkgPSBlZGdlSGlnaFB0LnkgLSBlZGdlTG93UHQueTtcblxuXHRcdFx0XHRpZiAoIE1hdGguYWJzKCBlZGdlRHkgKSA+IE51bWJlci5FUFNJTE9OICkge1xuXG5cdFx0XHRcdFx0Ly8gbm90IHBhcmFsbGVsXG5cdFx0XHRcdFx0aWYgKCBlZGdlRHkgPCAwICkge1xuXG5cdFx0XHRcdFx0XHRlZGdlTG93UHQgID0gaW5Qb2x5Z29uWyBxIF07IGVkZ2VEeCA9IC0gZWRnZUR4O1xuXHRcdFx0XHRcdFx0ZWRnZUhpZ2hQdCA9IGluUG9seWdvblsgcCBdOyBlZGdlRHkgPSAtIGVkZ2VEeTtcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoICggaW5QdC55IDwgZWRnZUxvd1B0LnkgKSB8fCAoIGluUHQueSA+IGVkZ2VIaWdoUHQueSApICkgXHRcdGNvbnRpbnVlO1xuXG5cdFx0XHRcdFx0aWYgKCBpblB0LnkgPT09IGVkZ2VMb3dQdC55ICkge1xuXG5cdFx0XHRcdFx0XHRpZiAoIGluUHQueCA9PT0gZWRnZUxvd1B0LnggKVx0XHRyZXR1cm5cdHRydWU7XHRcdC8vIGluUHQgaXMgb24gY29udG91ciA/XG5cdFx0XHRcdFx0XHQvLyBjb250aW51ZTtcdFx0XHRcdC8vIG5vIGludGVyc2VjdGlvbiBvciBlZGdlTG93UHQgPT4gZG9lc24ndCBjb3VudCAhISFcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdHZhciBwZXJwRWRnZSA9IGVkZ2VEeSAqICggaW5QdC54IC0gZWRnZUxvd1B0LnggKSAtIGVkZ2VEeCAqICggaW5QdC55IC0gZWRnZUxvd1B0LnkgKTtcblx0XHRcdFx0XHRcdGlmICggcGVycEVkZ2UgPT09IDAgKVx0XHRcdFx0cmV0dXJuXHR0cnVlO1x0XHQvLyBpblB0IGlzIG9uIGNvbnRvdXIgP1xuXHRcdFx0XHRcdFx0aWYgKCBwZXJwRWRnZSA8IDAgKSBcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0aW5zaWRlID0gISBpbnNpZGU7XHRcdC8vIHRydWUgaW50ZXJzZWN0aW9uIGxlZnQgb2YgaW5QdFxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHQvLyBwYXJhbGxlbCBvciBjb2xsaW5lYXJcblx0XHRcdFx0XHRpZiAoIGluUHQueSAhPT0gZWRnZUxvd1B0LnkgKSBcdFx0Y29udGludWU7XHRcdFx0Ly8gcGFyYWxsZWxcblx0XHRcdFx0XHQvLyBlZGdlIGxpZXMgb24gdGhlIHNhbWUgaG9yaXpvbnRhbCBsaW5lIGFzIGluUHRcblx0XHRcdFx0XHRpZiAoICggKCBlZGdlSGlnaFB0LnggPD0gaW5QdC54ICkgJiYgKCBpblB0LnggPD0gZWRnZUxvd1B0LnggKSApIHx8XG5cdFx0XHRcdFx0XHQgKCAoIGVkZ2VMb3dQdC54IDw9IGluUHQueCApICYmICggaW5QdC54IDw9IGVkZ2VIaWdoUHQueCApICkgKVx0XHRyZXR1cm5cdHRydWU7XHQvLyBpblB0OiBQb2ludCBvbiBjb250b3VyICFcblx0XHRcdFx0XHQvLyBjb250aW51ZTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuXHRpbnNpZGU7XG5cblx0XHR9XG5cblx0XHR2YXIgaXNDbG9ja1dpc2UgPSBTaGFwZVV0aWxzLmlzQ2xvY2tXaXNlO1xuXG5cdFx0dmFyIHN1YlBhdGhzID0gdGhpcy5zdWJQYXRocztcblx0XHRpZiAoIHN1YlBhdGhzLmxlbmd0aCA9PT0gMCApIHJldHVybiBbXTtcblxuXHRcdGlmICggbm9Ib2xlcyA9PT0gdHJ1ZSApXHRyZXR1cm5cdHRvU2hhcGVzTm9Ib2xlcyggc3ViUGF0aHMgKTtcblxuXG5cdFx0dmFyIHNvbGlkLCB0bXBQYXRoLCB0bXBTaGFwZSwgc2hhcGVzID0gW107XG5cblx0XHRpZiAoIHN1YlBhdGhzLmxlbmd0aCA9PT0gMSApIHtcblxuXHRcdFx0dG1wUGF0aCA9IHN1YlBhdGhzWyAwIF07XG5cdFx0XHR0bXBTaGFwZSA9IG5ldyBTaGFwZSgpO1xuXHRcdFx0dG1wU2hhcGUuY3VydmVzID0gdG1wUGF0aC5jdXJ2ZXM7XG5cdFx0XHRzaGFwZXMucHVzaCggdG1wU2hhcGUgKTtcblx0XHRcdHJldHVybiBzaGFwZXM7XG5cblx0XHR9XG5cblx0XHR2YXIgaG9sZXNGaXJzdCA9ICEgaXNDbG9ja1dpc2UoIHN1YlBhdGhzWyAwIF0uZ2V0UG9pbnRzKCkgKTtcblx0XHRob2xlc0ZpcnN0ID0gaXNDQ1cgPyAhIGhvbGVzRmlyc3QgOiBob2xlc0ZpcnN0O1xuXG5cdFx0Ly8gY29uc29sZS5sb2coXCJIb2xlcyBmaXJzdFwiLCBob2xlc0ZpcnN0KTtcblxuXHRcdHZhciBiZXR0ZXJTaGFwZUhvbGVzID0gW107XG5cdFx0dmFyIG5ld1NoYXBlcyA9IFtdO1xuXHRcdHZhciBuZXdTaGFwZUhvbGVzID0gW107XG5cdFx0dmFyIG1haW5JZHggPSAwO1xuXHRcdHZhciB0bXBQb2ludHM7XG5cblx0XHRuZXdTaGFwZXNbIG1haW5JZHggXSA9IHVuZGVmaW5lZDtcblx0XHRuZXdTaGFwZUhvbGVzWyBtYWluSWR4IF0gPSBbXTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IHN1YlBhdGhzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdHRtcFBhdGggPSBzdWJQYXRoc1sgaSBdO1xuXHRcdFx0dG1wUG9pbnRzID0gdG1wUGF0aC5nZXRQb2ludHMoKTtcblx0XHRcdHNvbGlkID0gaXNDbG9ja1dpc2UoIHRtcFBvaW50cyApO1xuXHRcdFx0c29saWQgPSBpc0NDVyA/ICEgc29saWQgOiBzb2xpZDtcblxuXHRcdFx0aWYgKCBzb2xpZCApIHtcblxuXHRcdFx0XHRpZiAoICggISBob2xlc0ZpcnN0ICkgJiYgKCBuZXdTaGFwZXNbIG1haW5JZHggXSApIClcdG1haW5JZHggKys7XG5cblx0XHRcdFx0bmV3U2hhcGVzWyBtYWluSWR4IF0gPSB7IHM6IG5ldyBTaGFwZSgpLCBwOiB0bXBQb2ludHMgfTtcblx0XHRcdFx0bmV3U2hhcGVzWyBtYWluSWR4IF0ucy5jdXJ2ZXMgPSB0bXBQYXRoLmN1cnZlcztcblxuXHRcdFx0XHRpZiAoIGhvbGVzRmlyc3QgKVx0bWFpbklkeCArKztcblx0XHRcdFx0bmV3U2hhcGVIb2xlc1sgbWFpbklkeCBdID0gW107XG5cblx0XHRcdFx0Ly9jb25zb2xlLmxvZygnY3cnLCBpKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRuZXdTaGFwZUhvbGVzWyBtYWluSWR4IF0ucHVzaCggeyBoOiB0bXBQYXRoLCBwOiB0bXBQb2ludHNbIDAgXSB9ICk7XG5cblx0XHRcdFx0Ly9jb25zb2xlLmxvZygnY2N3JywgaSk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdC8vIG9ubHkgSG9sZXM/IC0+IHByb2JhYmx5IGFsbCBTaGFwZXMgd2l0aCB3cm9uZyBvcmllbnRhdGlvblxuXHRcdGlmICggISBuZXdTaGFwZXNbIDAgXSApXHRyZXR1cm5cdHRvU2hhcGVzTm9Ib2xlcyggc3ViUGF0aHMgKTtcblxuXG5cdFx0aWYgKCBuZXdTaGFwZXMubGVuZ3RoID4gMSApIHtcblxuXHRcdFx0dmFyIGFtYmlndW91cyA9IGZhbHNlO1xuXHRcdFx0dmFyIHRvQ2hhbmdlID0gW107XG5cblx0XHRcdGZvciAoIHZhciBzSWR4ID0gMCwgc0xlbiA9IG5ld1NoYXBlcy5sZW5ndGg7IHNJZHggPCBzTGVuOyBzSWR4ICsrICkge1xuXG5cdFx0XHRcdGJldHRlclNoYXBlSG9sZXNbIHNJZHggXSA9IFtdO1xuXG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIHZhciBzSWR4ID0gMCwgc0xlbiA9IG5ld1NoYXBlcy5sZW5ndGg7IHNJZHggPCBzTGVuOyBzSWR4ICsrICkge1xuXG5cdFx0XHRcdHZhciBzaG8gPSBuZXdTaGFwZUhvbGVzWyBzSWR4IF07XG5cblx0XHRcdFx0Zm9yICggdmFyIGhJZHggPSAwOyBoSWR4IDwgc2hvLmxlbmd0aDsgaElkeCArKyApIHtcblxuXHRcdFx0XHRcdHZhciBobyA9IHNob1sgaElkeCBdO1xuXHRcdFx0XHRcdHZhciBob2xlX3VuYXNzaWduZWQgPSB0cnVlO1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIHMySWR4ID0gMDsgczJJZHggPCBuZXdTaGFwZXMubGVuZ3RoOyBzMklkeCArKyApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBpc1BvaW50SW5zaWRlUG9seWdvbiggaG8ucCwgbmV3U2hhcGVzWyBzMklkeCBdLnAgKSApIHtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHNJZHggIT09IHMySWR4IClcdHRvQ2hhbmdlLnB1c2goIHsgZnJvbXM6IHNJZHgsIHRvczogczJJZHgsIGhvbGU6IGhJZHggfSApO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGhvbGVfdW5hc3NpZ25lZCApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGhvbGVfdW5hc3NpZ25lZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdGJldHRlclNoYXBlSG9sZXNbIHMySWR4IF0ucHVzaCggaG8gKTtcblxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0YW1iaWd1b3VzID0gdHJ1ZTtcblxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIGhvbGVfdW5hc3NpZ25lZCApIHtcblxuXHRcdFx0XHRcdFx0YmV0dGVyU2hhcGVIb2xlc1sgc0lkeCBdLnB1c2goIGhvICk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhcImFtYmlndW91czogXCIsIGFtYmlndW91cyk7XG5cdFx0XHRpZiAoIHRvQ2hhbmdlLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdFx0Ly8gY29uc29sZS5sb2coXCJ0byBjaGFuZ2U6IFwiLCB0b0NoYW5nZSk7XG5cdFx0XHRcdGlmICggISBhbWJpZ3VvdXMgKVx0bmV3U2hhcGVIb2xlcyA9IGJldHRlclNoYXBlSG9sZXM7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHZhciB0bXBIb2xlcztcblxuXHRcdGZvciAoIHZhciBpID0gMCwgaWwgPSBuZXdTaGFwZXMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XG5cblx0XHRcdHRtcFNoYXBlID0gbmV3U2hhcGVzWyBpIF0ucztcblx0XHRcdHNoYXBlcy5wdXNoKCB0bXBTaGFwZSApO1xuXHRcdFx0dG1wSG9sZXMgPSBuZXdTaGFwZUhvbGVzWyBpIF07XG5cblx0XHRcdGZvciAoIHZhciBqID0gMCwgamwgPSB0bXBIb2xlcy5sZW5ndGg7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHR0bXBTaGFwZS5ob2xlcy5wdXNoKCB0bXBIb2xlc1sgaiBdLmggKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly9jb25zb2xlLmxvZyhcInNoYXBlXCIsIHNoYXBlcyk7XG5cblx0XHRyZXR1cm4gc2hhcGVzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3Igeno4NSAvIGh0dHA6Ly93d3cubGFiNGdhbWVzLm5ldC96ejg1L2Jsb2dcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gRm9udCggZGF0YSApIHtcblxuXHR0aGlzLmRhdGEgPSBkYXRhO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEZvbnQucHJvdG90eXBlLCB7XG5cblx0aXNGb250OiB0cnVlLFxuXG5cdGdlbmVyYXRlU2hhcGVzOiBmdW5jdGlvbiAoIHRleHQsIHNpemUsIGRpdmlzaW9ucyApIHtcblxuXHRcdGZ1bmN0aW9uIGNyZWF0ZVBhdGhzKCB0ZXh0ICkge1xuXG5cdFx0XHR2YXIgY2hhcnMgPSBTdHJpbmcoIHRleHQgKS5zcGxpdCggJycgKTtcblx0XHRcdHZhciBzY2FsZSA9IHNpemUgLyBkYXRhLnJlc29sdXRpb247XG5cdFx0XHR2YXIgbGluZV9oZWlnaHQgPSAoIGRhdGEuYm91bmRpbmdCb3gueU1heCAtIGRhdGEuYm91bmRpbmdCb3gueU1pbiArIGRhdGEudW5kZXJsaW5lVGhpY2tuZXNzICkgKiBzY2FsZTtcblxuXHRcdFx0dmFyIG9mZnNldFggPSAwLCBvZmZzZXRZID0gMDtcblxuXHRcdFx0dmFyIHBhdGhzID0gW107XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGNoYXJzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHR2YXIgY2hhciA9IGNoYXJzWyBpIF07XG5cblx0XHRcdFx0aWYgKCBjaGFyID09PSAnXFxuJyApIHtcblxuXHRcdFx0XHRcdG9mZnNldFggPSAwO1xuXHRcdFx0XHRcdG9mZnNldFkgLT0gbGluZV9oZWlnaHQ7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHZhciByZXQgPSBjcmVhdGVQYXRoKCBjaGFyLCBzY2FsZSwgb2Zmc2V0WCwgb2Zmc2V0WSApO1xuXHRcdFx0XHRcdG9mZnNldFggKz0gcmV0Lm9mZnNldFg7XG5cdFx0XHRcdFx0cGF0aHMucHVzaCggcmV0LnBhdGggKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHBhdGhzO1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gY3JlYXRlUGF0aCggYywgc2NhbGUsIG9mZnNldFgsIG9mZnNldFkgKSB7XG5cblx0XHRcdHZhciBnbHlwaCA9IGRhdGEuZ2x5cGhzWyBjIF0gfHwgZGF0YS5nbHlwaHNbICc/JyBdO1xuXG5cdFx0XHRpZiAoICEgZ2x5cGggKSByZXR1cm47XG5cblx0XHRcdHZhciBwYXRoID0gbmV3IFNoYXBlUGF0aCgpO1xuXG5cdFx0XHR2YXIgcHRzID0gW107XG5cdFx0XHR2YXIgeCwgeSwgY3B4LCBjcHksIGNweDAsIGNweTAsIGNweDEsIGNweTEsIGNweDIsIGNweTIsIGxhc3RlO1xuXG5cdFx0XHRpZiAoIGdseXBoLm8gKSB7XG5cblx0XHRcdFx0dmFyIG91dGxpbmUgPSBnbHlwaC5fY2FjaGVkT3V0bGluZSB8fCAoIGdseXBoLl9jYWNoZWRPdXRsaW5lID0gZ2x5cGguby5zcGxpdCggJyAnICkgKTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBvdXRsaW5lLmxlbmd0aDsgaSA8IGw7ICkge1xuXG5cdFx0XHRcdFx0dmFyIGFjdGlvbiA9IG91dGxpbmVbIGkgKysgXTtcblxuXHRcdFx0XHRcdHN3aXRjaCAoIGFjdGlvbiApIHtcblxuXHRcdFx0XHRcdFx0Y2FzZSAnbSc6IC8vIG1vdmVUb1xuXG5cdFx0XHRcdFx0XHRcdHggPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFg7XG5cdFx0XHRcdFx0XHRcdHkgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFk7XG5cblx0XHRcdFx0XHRcdFx0cGF0aC5tb3ZlVG8oIHgsIHkgKTtcblxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0Y2FzZSAnbCc6IC8vIGxpbmVUb1xuXG5cdFx0XHRcdFx0XHRcdHggPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFg7XG5cdFx0XHRcdFx0XHRcdHkgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFk7XG5cblx0XHRcdFx0XHRcdFx0cGF0aC5saW5lVG8oIHgsIHkgKTtcblxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0Y2FzZSAncSc6IC8vIHF1YWRyYXRpY0N1cnZlVG9cblxuXHRcdFx0XHRcdFx0XHRjcHggID0gb3V0bGluZVsgaSArKyBdICogc2NhbGUgKyBvZmZzZXRYO1xuXHRcdFx0XHRcdFx0XHRjcHkgID0gb3V0bGluZVsgaSArKyBdICogc2NhbGUgKyBvZmZzZXRZO1xuXHRcdFx0XHRcdFx0XHRjcHgxID0gb3V0bGluZVsgaSArKyBdICogc2NhbGUgKyBvZmZzZXRYO1xuXHRcdFx0XHRcdFx0XHRjcHkxID0gb3V0bGluZVsgaSArKyBdICogc2NhbGUgKyBvZmZzZXRZO1xuXG5cdFx0XHRcdFx0XHRcdHBhdGgucXVhZHJhdGljQ3VydmVUbyggY3B4MSwgY3B5MSwgY3B4LCBjcHkgKTtcblxuXHRcdFx0XHRcdFx0XHRsYXN0ZSA9IHB0c1sgcHRzLmxlbmd0aCAtIDEgXTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIGxhc3RlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Y3B4MCA9IGxhc3RlLng7XG5cdFx0XHRcdFx0XHRcdFx0Y3B5MCA9IGxhc3RlLnk7XG5cblx0XHRcdFx0XHRcdFx0XHRmb3IgKCB2YXIgaTIgPSAxOyBpMiA8PSBkaXZpc2lvbnM7IGkyICsrICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHR2YXIgdCA9IGkyIC8gZGl2aXNpb25zO1xuXHRcdFx0XHRcdFx0XHRcdFx0UXVhZHJhdGljQmV6aWVyKCB0LCBjcHgwLCBjcHgxLCBjcHggKTtcblx0XHRcdFx0XHRcdFx0XHRcdFF1YWRyYXRpY0JlemllciggdCwgY3B5MCwgY3B5MSwgY3B5ICk7XG5cblx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRjYXNlICdiJzogLy8gYmV6aWVyQ3VydmVUb1xuXG5cdFx0XHRcdFx0XHRcdGNweCAgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFg7XG5cdFx0XHRcdFx0XHRcdGNweSAgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFk7XG5cdFx0XHRcdFx0XHRcdGNweDEgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFg7XG5cdFx0XHRcdFx0XHRcdGNweTEgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFk7XG5cdFx0XHRcdFx0XHRcdGNweDIgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFg7XG5cdFx0XHRcdFx0XHRcdGNweTIgPSBvdXRsaW5lWyBpICsrIF0gKiBzY2FsZSArIG9mZnNldFk7XG5cblx0XHRcdFx0XHRcdFx0cGF0aC5iZXppZXJDdXJ2ZVRvKCBjcHgxLCBjcHkxLCBjcHgyLCBjcHkyLCBjcHgsIGNweSApO1xuXG5cdFx0XHRcdFx0XHRcdGxhc3RlID0gcHRzWyBwdHMubGVuZ3RoIC0gMSBdO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggbGFzdGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRjcHgwID0gbGFzdGUueDtcblx0XHRcdFx0XHRcdFx0XHRjcHkwID0gbGFzdGUueTtcblxuXHRcdFx0XHRcdFx0XHRcdGZvciAoIHZhciBpMiA9IDE7IGkyIDw9IGRpdmlzaW9uczsgaTIgKysgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdHZhciB0ID0gaTIgLyBkaXZpc2lvbnM7XG5cdFx0XHRcdFx0XHRcdFx0XHRDdWJpY0JlemllciggdCwgY3B4MCwgY3B4MSwgY3B4MiwgY3B4ICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRDdWJpY0JlemllciggdCwgY3B5MCwgY3B5MSwgY3B5MiwgY3B5ICk7XG5cblx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4geyBvZmZzZXRYOiBnbHlwaC5oYSAqIHNjYWxlLCBwYXRoOiBwYXRoIH07XG5cblx0XHR9XG5cblx0XHQvL1xuXG5cdFx0aWYgKCBzaXplID09PSB1bmRlZmluZWQgKSBzaXplID0gMTAwO1xuXHRcdGlmICggZGl2aXNpb25zID09PSB1bmRlZmluZWQgKSBkaXZpc2lvbnMgPSA0O1xuXG5cdFx0dmFyIGRhdGEgPSB0aGlzLmRhdGE7XG5cblx0XHR2YXIgcGF0aHMgPSBjcmVhdGVQYXRocyggdGV4dCApO1xuXHRcdHZhciBzaGFwZXMgPSBbXTtcblxuXHRcdGZvciAoIHZhciBwID0gMCwgcGwgPSBwYXRocy5sZW5ndGg7IHAgPCBwbDsgcCArKyApIHtcblxuXHRcdFx0QXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoIHNoYXBlcywgcGF0aHNbIHAgXS50b1NoYXBlcygpICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gc2hhcGVzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gRm9udExvYWRlciggbWFuYWdlciApIHtcblxuXHR0aGlzLm1hbmFnZXIgPSAoIG1hbmFnZXIgIT09IHVuZGVmaW5lZCApID8gbWFuYWdlciA6IERlZmF1bHRMb2FkaW5nTWFuYWdlcjtcblxufVxuXG5PYmplY3QuYXNzaWduKCBGb250TG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dmFyIGxvYWRlciA9IG5ldyBGaWxlTG9hZGVyKCB0aGlzLm1hbmFnZXIgKTtcblx0XHRsb2FkZXIubG9hZCggdXJsLCBmdW5jdGlvbiAoIHRleHQgKSB7XG5cblx0XHRcdHZhciBqc29uO1xuXG5cdFx0XHR0cnkge1xuXG5cdFx0XHRcdGpzb24gPSBKU09OLnBhcnNlKCB0ZXh0ICk7XG5cblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkZvbnRMb2FkZXI6IHR5cGVmYWNlLmpzIHN1cHBvcnQgaXMgYmVpbmcgZGVwcmVjYXRlZC4gVXNlIHR5cGVmYWNlLmpzb24gaW5zdGVhZC4nICk7XG5cdFx0XHRcdGpzb24gPSBKU09OLnBhcnNlKCB0ZXh0LnN1YnN0cmluZyggNjUsIHRleHQubGVuZ3RoIC0gMiApICk7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIGZvbnQgPSBzY29wZS5wYXJzZSgganNvbiApO1xuXG5cdFx0XHRpZiAoIG9uTG9hZCApIG9uTG9hZCggZm9udCApO1xuXG5cdFx0fSwgb25Qcm9ncmVzcywgb25FcnJvciApO1xuXG5cdH0sXG5cblx0cGFyc2U6IGZ1bmN0aW9uICgganNvbiApIHtcblxuXHRcdHJldHVybiBuZXcgRm9udCgganNvbiApO1xuXG5cdH1cblxufSApO1xuXG52YXIgY29udGV4dDtcblxudmFyIEF1ZGlvQ29udGV4dCA9IHtcblxuXHRnZXRDb250ZXh0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRpZiAoIGNvbnRleHQgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Y29udGV4dCA9IG5ldyAoIHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dCApKCk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gY29udGV4dDtcblxuXHR9LFxuXG5cdHNldENvbnRleHQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRjb250ZXh0ID0gdmFsdWU7XG5cblx0fVxuXG59O1xuXG4vKipcbiAqIEBhdXRob3IgUmVlY2UgQWFyb24gTGVjcml2YWluIC8gaHR0cDovL3JlZWNlbm90ZXMuY29tL1xuICovXG5cbmZ1bmN0aW9uIEF1ZGlvTG9hZGVyKCBtYW5hZ2VyICkge1xuXG5cdHRoaXMubWFuYWdlciA9ICggbWFuYWdlciAhPT0gdW5kZWZpbmVkICkgPyBtYW5hZ2VyIDogRGVmYXVsdExvYWRpbmdNYW5hZ2VyO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEF1ZGlvTG9hZGVyLnByb3RvdHlwZSwge1xuXG5cdGxvYWQ6IGZ1bmN0aW9uICggdXJsLCBvbkxvYWQsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IgKSB7XG5cblx0XHR2YXIgbG9hZGVyID0gbmV3IEZpbGVMb2FkZXIoIHRoaXMubWFuYWdlciApO1xuXHRcdGxvYWRlci5zZXRSZXNwb25zZVR5cGUoICdhcnJheWJ1ZmZlcicgKTtcblx0XHRsb2FkZXIubG9hZCggdXJsLCBmdW5jdGlvbiAoIGJ1ZmZlciApIHtcblxuXHRcdFx0dmFyIGNvbnRleHQgPSBBdWRpb0NvbnRleHQuZ2V0Q29udGV4dCgpO1xuXG5cdFx0XHRjb250ZXh0LmRlY29kZUF1ZGlvRGF0YSggYnVmZmVyLCBmdW5jdGlvbiAoIGF1ZGlvQnVmZmVyICkge1xuXG5cdFx0XHRcdG9uTG9hZCggYXVkaW9CdWZmZXIgKTtcblxuXHRcdFx0fSApO1xuXG5cdFx0fSwgb25Qcm9ncmVzcywgb25FcnJvciApO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gU3RlcmVvQ2FtZXJhKCkge1xuXG5cdHRoaXMudHlwZSA9ICdTdGVyZW9DYW1lcmEnO1xuXG5cdHRoaXMuYXNwZWN0ID0gMTtcblxuXHR0aGlzLmV5ZVNlcCA9IDAuMDY0O1xuXG5cdHRoaXMuY2FtZXJhTCA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSgpO1xuXHR0aGlzLmNhbWVyYUwubGF5ZXJzLmVuYWJsZSggMSApO1xuXHR0aGlzLmNhbWVyYUwubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXG5cdHRoaXMuY2FtZXJhUiA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSgpO1xuXHR0aGlzLmNhbWVyYVIubGF5ZXJzLmVuYWJsZSggMiApO1xuXHR0aGlzLmNhbWVyYVIubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFN0ZXJlb0NhbWVyYS5wcm90b3R5cGUsIHtcblxuXHR1cGRhdGU6ICggZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGluc3RhbmNlLCBmb2N1cywgZm92LCBhc3BlY3QsIG5lYXIsIGZhciwgem9vbSwgZXllU2VwO1xuXG5cdFx0dmFyIGV5ZVJpZ2h0ID0gbmV3IE1hdHJpeDQoKTtcblx0XHR2YXIgZXllTGVmdCA9IG5ldyBNYXRyaXg0KCk7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCBjYW1lcmEgKSB7XG5cblx0XHRcdHZhciBuZWVkc1VwZGF0ZSA9IGluc3RhbmNlICE9PSB0aGlzIHx8IGZvY3VzICE9PSBjYW1lcmEuZm9jdXMgfHwgZm92ICE9PSBjYW1lcmEuZm92IHx8XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhc3BlY3QgIT09IGNhbWVyYS5hc3BlY3QgKiB0aGlzLmFzcGVjdCB8fCBuZWFyICE9PSBjYW1lcmEubmVhciB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZmFyICE9PSBjYW1lcmEuZmFyIHx8IHpvb20gIT09IGNhbWVyYS56b29tIHx8IGV5ZVNlcCAhPT0gdGhpcy5leWVTZXA7XG5cblx0XHRcdGlmICggbmVlZHNVcGRhdGUgKSB7XG5cblx0XHRcdFx0aW5zdGFuY2UgPSB0aGlzO1xuXHRcdFx0XHRmb2N1cyA9IGNhbWVyYS5mb2N1cztcblx0XHRcdFx0Zm92ID0gY2FtZXJhLmZvdjtcblx0XHRcdFx0YXNwZWN0ID0gY2FtZXJhLmFzcGVjdCAqIHRoaXMuYXNwZWN0O1xuXHRcdFx0XHRuZWFyID0gY2FtZXJhLm5lYXI7XG5cdFx0XHRcdGZhciA9IGNhbWVyYS5mYXI7XG5cdFx0XHRcdHpvb20gPSBjYW1lcmEuem9vbTtcblxuXHRcdFx0XHQvLyBPZmYtYXhpcyBzdGVyZW9zY29waWMgZWZmZWN0IGJhc2VkIG9uXG5cdFx0XHRcdC8vIGh0dHA6Ly9wYXVsYm91cmtlLm5ldC9zdGVyZW9ncmFwaGljcy9zdGVyZW9yZW5kZXIvXG5cblx0XHRcdFx0dmFyIHByb2plY3Rpb25NYXRyaXggPSBjYW1lcmEucHJvamVjdGlvbk1hdHJpeC5jbG9uZSgpO1xuXHRcdFx0XHRleWVTZXAgPSB0aGlzLmV5ZVNlcCAvIDI7XG5cdFx0XHRcdHZhciBleWVTZXBPblByb2plY3Rpb24gPSBleWVTZXAgKiBuZWFyIC8gZm9jdXM7XG5cdFx0XHRcdHZhciB5bWF4ID0gKCBuZWFyICogTWF0aC50YW4oIF9NYXRoLkRFRzJSQUQgKiBmb3YgKiAwLjUgKSApIC8gem9vbTtcblx0XHRcdFx0dmFyIHhtaW4sIHhtYXg7XG5cblx0XHRcdFx0Ly8gdHJhbnNsYXRlIHhPZmZzZXRcblxuXHRcdFx0XHRleWVMZWZ0LmVsZW1lbnRzWyAxMiBdID0gLSBleWVTZXA7XG5cdFx0XHRcdGV5ZVJpZ2h0LmVsZW1lbnRzWyAxMiBdID0gZXllU2VwO1xuXG5cdFx0XHRcdC8vIGZvciBsZWZ0IGV5ZVxuXG5cdFx0XHRcdHhtaW4gPSAtIHltYXggKiBhc3BlY3QgKyBleWVTZXBPblByb2plY3Rpb247XG5cdFx0XHRcdHhtYXggPSB5bWF4ICogYXNwZWN0ICsgZXllU2VwT25Qcm9qZWN0aW9uO1xuXG5cdFx0XHRcdHByb2plY3Rpb25NYXRyaXguZWxlbWVudHNbIDAgXSA9IDIgKiBuZWFyIC8gKCB4bWF4IC0geG1pbiApO1xuXHRcdFx0XHRwcm9qZWN0aW9uTWF0cml4LmVsZW1lbnRzWyA4IF0gPSAoIHhtYXggKyB4bWluICkgLyAoIHhtYXggLSB4bWluICk7XG5cblx0XHRcdFx0dGhpcy5jYW1lcmFMLnByb2plY3Rpb25NYXRyaXguY29weSggcHJvamVjdGlvbk1hdHJpeCApO1xuXG5cdFx0XHRcdC8vIGZvciByaWdodCBleWVcblxuXHRcdFx0XHR4bWluID0gLSB5bWF4ICogYXNwZWN0IC0gZXllU2VwT25Qcm9qZWN0aW9uO1xuXHRcdFx0XHR4bWF4ID0geW1heCAqIGFzcGVjdCAtIGV5ZVNlcE9uUHJvamVjdGlvbjtcblxuXHRcdFx0XHRwcm9qZWN0aW9uTWF0cml4LmVsZW1lbnRzWyAwIF0gPSAyICogbmVhciAvICggeG1heCAtIHhtaW4gKTtcblx0XHRcdFx0cHJvamVjdGlvbk1hdHJpeC5lbGVtZW50c1sgOCBdID0gKCB4bWF4ICsgeG1pbiApIC8gKCB4bWF4IC0geG1pbiApO1xuXG5cdFx0XHRcdHRoaXMuY2FtZXJhUi5wcm9qZWN0aW9uTWF0cml4LmNvcHkoIHByb2plY3Rpb25NYXRyaXggKTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmNhbWVyYUwubWF0cml4V29ybGQuY29weSggY2FtZXJhLm1hdHJpeFdvcmxkICkubXVsdGlwbHkoIGV5ZUxlZnQgKTtcblx0XHRcdHRoaXMuY2FtZXJhUi5tYXRyaXhXb3JsZC5jb3B5KCBjYW1lcmEubWF0cml4V29ybGQgKS5tdWx0aXBseSggZXllUmlnaHQgKTtcblxuXHRcdH07XG5cblx0fSApKClcblxufSApO1xuXG4vKipcbiAqIENhbWVyYSBmb3IgcmVuZGVyaW5nIGN1YmUgbWFwc1xuICpcdC0gcmVuZGVycyBzY2VuZSBpbnRvIGF4aXMtYWxpZ25lZCBjdWJlXG4gKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBDdWJlQ2FtZXJhKCBuZWFyLCBmYXIsIGN1YmVSZXNvbHV0aW9uICkge1xuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnR5cGUgPSAnQ3ViZUNhbWVyYSc7XG5cblx0dmFyIGZvdiA9IDkwLCBhc3BlY3QgPSAxO1xuXG5cdHZhciBjYW1lcmFQWCA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSggZm92LCBhc3BlY3QsIG5lYXIsIGZhciApO1xuXHRjYW1lcmFQWC51cC5zZXQoIDAsIC0gMSwgMCApO1xuXHRjYW1lcmFQWC5sb29rQXQoIG5ldyBWZWN0b3IzKCAxLCAwLCAwICkgKTtcblx0dGhpcy5hZGQoIGNhbWVyYVBYICk7XG5cblx0dmFyIGNhbWVyYU5YID0gbmV3IFBlcnNwZWN0aXZlQ2FtZXJhKCBmb3YsIGFzcGVjdCwgbmVhciwgZmFyICk7XG5cdGNhbWVyYU5YLnVwLnNldCggMCwgLSAxLCAwICk7XG5cdGNhbWVyYU5YLmxvb2tBdCggbmV3IFZlY3RvcjMoIC0gMSwgMCwgMCApICk7XG5cdHRoaXMuYWRkKCBjYW1lcmFOWCApO1xuXG5cdHZhciBjYW1lcmFQWSA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSggZm92LCBhc3BlY3QsIG5lYXIsIGZhciApO1xuXHRjYW1lcmFQWS51cC5zZXQoIDAsIDAsIDEgKTtcblx0Y2FtZXJhUFkubG9va0F0KCBuZXcgVmVjdG9yMyggMCwgMSwgMCApICk7XG5cdHRoaXMuYWRkKCBjYW1lcmFQWSApO1xuXG5cdHZhciBjYW1lcmFOWSA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSggZm92LCBhc3BlY3QsIG5lYXIsIGZhciApO1xuXHRjYW1lcmFOWS51cC5zZXQoIDAsIDAsIC0gMSApO1xuXHRjYW1lcmFOWS5sb29rQXQoIG5ldyBWZWN0b3IzKCAwLCAtIDEsIDAgKSApO1xuXHR0aGlzLmFkZCggY2FtZXJhTlkgKTtcblxuXHR2YXIgY2FtZXJhUFogPSBuZXcgUGVyc3BlY3RpdmVDYW1lcmEoIGZvdiwgYXNwZWN0LCBuZWFyLCBmYXIgKTtcblx0Y2FtZXJhUFoudXAuc2V0KCAwLCAtIDEsIDAgKTtcblx0Y2FtZXJhUFoubG9va0F0KCBuZXcgVmVjdG9yMyggMCwgMCwgMSApICk7XG5cdHRoaXMuYWRkKCBjYW1lcmFQWiApO1xuXG5cdHZhciBjYW1lcmFOWiA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSggZm92LCBhc3BlY3QsIG5lYXIsIGZhciApO1xuXHRjYW1lcmFOWi51cC5zZXQoIDAsIC0gMSwgMCApO1xuXHRjYW1lcmFOWi5sb29rQXQoIG5ldyBWZWN0b3IzKCAwLCAwLCAtIDEgKSApO1xuXHR0aGlzLmFkZCggY2FtZXJhTlogKTtcblxuXHR2YXIgb3B0aW9ucyA9IHsgZm9ybWF0OiBSR0JGb3JtYXQsIG1hZ0ZpbHRlcjogTGluZWFyRmlsdGVyLCBtaW5GaWx0ZXI6IExpbmVhckZpbHRlciB9O1xuXG5cdHRoaXMucmVuZGVyVGFyZ2V0ID0gbmV3IFdlYkdMUmVuZGVyVGFyZ2V0Q3ViZSggY3ViZVJlc29sdXRpb24sIGN1YmVSZXNvbHV0aW9uLCBvcHRpb25zICk7XG5cdHRoaXMucmVuZGVyVGFyZ2V0LnRleHR1cmUubmFtZSA9IFwiQ3ViZUNhbWVyYVwiO1xuXG5cdHRoaXMudXBkYXRlQ3ViZU1hcCA9IGZ1bmN0aW9uICggcmVuZGVyZXIsIHNjZW5lICkge1xuXG5cdFx0aWYgKCB0aGlzLnBhcmVudCA9PT0gbnVsbCApIHRoaXMudXBkYXRlTWF0cml4V29ybGQoKTtcblxuXHRcdHZhciByZW5kZXJUYXJnZXQgPSB0aGlzLnJlbmRlclRhcmdldDtcblx0XHR2YXIgZ2VuZXJhdGVNaXBtYXBzID0gcmVuZGVyVGFyZ2V0LnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzO1xuXG5cdFx0cmVuZGVyVGFyZ2V0LnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzID0gZmFsc2U7XG5cblx0XHRyZW5kZXJUYXJnZXQuYWN0aXZlQ3ViZUZhY2UgPSAwO1xuXHRcdHJlbmRlcmVyLnJlbmRlciggc2NlbmUsIGNhbWVyYVBYLCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdHJlbmRlclRhcmdldC5hY3RpdmVDdWJlRmFjZSA9IDE7XG5cdFx0cmVuZGVyZXIucmVuZGVyKCBzY2VuZSwgY2FtZXJhTlgsIHJlbmRlclRhcmdldCApO1xuXG5cdFx0cmVuZGVyVGFyZ2V0LmFjdGl2ZUN1YmVGYWNlID0gMjtcblx0XHRyZW5kZXJlci5yZW5kZXIoIHNjZW5lLCBjYW1lcmFQWSwgcmVuZGVyVGFyZ2V0ICk7XG5cblx0XHRyZW5kZXJUYXJnZXQuYWN0aXZlQ3ViZUZhY2UgPSAzO1xuXHRcdHJlbmRlcmVyLnJlbmRlciggc2NlbmUsIGNhbWVyYU5ZLCByZW5kZXJUYXJnZXQgKTtcblxuXHRcdHJlbmRlclRhcmdldC5hY3RpdmVDdWJlRmFjZSA9IDQ7XG5cdFx0cmVuZGVyZXIucmVuZGVyKCBzY2VuZSwgY2FtZXJhUFosIHJlbmRlclRhcmdldCApO1xuXG5cdFx0cmVuZGVyVGFyZ2V0LnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzID0gZ2VuZXJhdGVNaXBtYXBzO1xuXG5cdFx0cmVuZGVyVGFyZ2V0LmFjdGl2ZUN1YmVGYWNlID0gNTtcblx0XHRyZW5kZXJlci5yZW5kZXIoIHNjZW5lLCBjYW1lcmFOWiwgcmVuZGVyVGFyZ2V0ICk7XG5cblx0XHRyZW5kZXJlci5zZXRSZW5kZXJUYXJnZXQoIG51bGwgKTtcblxuXHR9O1xuXG59XG5cbkN1YmVDYW1lcmEucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICk7XG5DdWJlQ2FtZXJhLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEN1YmVDYW1lcmE7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBBcnJheUNhbWVyYSggYXJyYXkgKSB7XG5cblx0UGVyc3BlY3RpdmVDYW1lcmEuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMuZW5hYmxlZCA9IGZhbHNlO1xuXHR0aGlzLmNhbWVyYXMgPSBhcnJheSB8fCBbXTtcblxufVxuXG5BcnJheUNhbWVyYS5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBQZXJzcGVjdGl2ZUNhbWVyYS5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBBcnJheUNhbWVyYSxcblxuXHRpc0FycmF5Q2FtZXJhOiB0cnVlXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEF1ZGlvTGlzdGVuZXIoKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudHlwZSA9ICdBdWRpb0xpc3RlbmVyJztcblxuXHR0aGlzLmNvbnRleHQgPSBBdWRpb0NvbnRleHQuZ2V0Q29udGV4dCgpO1xuXG5cdHRoaXMuZ2FpbiA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG5cdHRoaXMuZ2Fpbi5jb25uZWN0KCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24gKTtcblxuXHR0aGlzLmZpbHRlciA9IG51bGw7XG5cbn1cblxuQXVkaW9MaXN0ZW5lci5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBPYmplY3QzRC5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBBdWRpb0xpc3RlbmVyLFxuXG5cdGdldElucHV0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5nYWluO1xuXG5cdH0sXG5cblx0cmVtb3ZlRmlsdGVyOiBmdW5jdGlvbiAoICkge1xuXG5cdFx0aWYgKCB0aGlzLmZpbHRlciAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5nYWluLmRpc2Nvbm5lY3QoIHRoaXMuZmlsdGVyICk7XG5cdFx0XHR0aGlzLmZpbHRlci5kaXNjb25uZWN0KCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24gKTtcblx0XHRcdHRoaXMuZ2Fpbi5jb25uZWN0KCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24gKTtcblx0XHRcdHRoaXMuZmlsdGVyID0gbnVsbDtcblxuXHRcdH1cblxuXHR9LFxuXG5cdGdldEZpbHRlcjogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyO1xuXG5cdH0sXG5cblx0c2V0RmlsdGVyOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0aWYgKCB0aGlzLmZpbHRlciAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5nYWluLmRpc2Nvbm5lY3QoIHRoaXMuZmlsdGVyICk7XG5cdFx0XHR0aGlzLmZpbHRlci5kaXNjb25uZWN0KCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24gKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRoaXMuZ2Fpbi5kaXNjb25uZWN0KCB0aGlzLmNvbnRleHQuZGVzdGluYXRpb24gKTtcblxuXHRcdH1cblxuXHRcdHRoaXMuZmlsdGVyID0gdmFsdWU7XG5cdFx0dGhpcy5nYWluLmNvbm5lY3QoIHRoaXMuZmlsdGVyICk7XG5cdFx0dGhpcy5maWx0ZXIuY29ubmVjdCggdGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uICk7XG5cblx0fSxcblxuXHRnZXRNYXN0ZXJWb2x1bWU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLmdhaW4uZ2Fpbi52YWx1ZTtcblxuXHR9LFxuXG5cdHNldE1hc3RlclZvbHVtZTogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMuZ2Fpbi5nYWluLnZhbHVlID0gdmFsdWU7XG5cblx0fSxcblxuXHR1cGRhdGVNYXRyaXhXb3JsZDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcG9zaXRpb24gPSBuZXcgVmVjdG9yMygpO1xuXHRcdHZhciBxdWF0ZXJuaW9uID0gbmV3IFF1YXRlcm5pb24oKTtcblx0XHR2YXIgc2NhbGUgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0dmFyIG9yaWVudGF0aW9uID0gbmV3IFZlY3RvcjMoKTtcblxuXHRcdHJldHVybiBmdW5jdGlvbiB1cGRhdGVNYXRyaXhXb3JsZCggZm9yY2UgKSB7XG5cblx0XHRcdE9iamVjdDNELnByb3RvdHlwZS51cGRhdGVNYXRyaXhXb3JsZC5jYWxsKCB0aGlzLCBmb3JjZSApO1xuXG5cdFx0XHR2YXIgbGlzdGVuZXIgPSB0aGlzLmNvbnRleHQubGlzdGVuZXI7XG5cdFx0XHR2YXIgdXAgPSB0aGlzLnVwO1xuXG5cdFx0XHR0aGlzLm1hdHJpeFdvcmxkLmRlY29tcG9zZSggcG9zaXRpb24sIHF1YXRlcm5pb24sIHNjYWxlICk7XG5cblx0XHRcdG9yaWVudGF0aW9uLnNldCggMCwgMCwgLSAxICkuYXBwbHlRdWF0ZXJuaW9uKCBxdWF0ZXJuaW9uICk7XG5cblx0XHRcdGlmICggbGlzdGVuZXIucG9zaXRpb25YICkge1xuXG5cdFx0XHRcdGxpc3RlbmVyLnBvc2l0aW9uWC5zZXRWYWx1ZUF0VGltZSggcG9zaXRpb24ueCwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLnBvc2l0aW9uWS5zZXRWYWx1ZUF0VGltZSggcG9zaXRpb24ueSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLnBvc2l0aW9uWi5zZXRWYWx1ZUF0VGltZSggcG9zaXRpb24ueiwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLmZvcndhcmRYLnNldFZhbHVlQXRUaW1lKCBvcmllbnRhdGlvbi54LCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKTtcblx0XHRcdFx0bGlzdGVuZXIuZm9yd2FyZFkuc2V0VmFsdWVBdFRpbWUoIG9yaWVudGF0aW9uLnksIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSApO1xuXHRcdFx0XHRsaXN0ZW5lci5mb3J3YXJkWi5zZXRWYWx1ZUF0VGltZSggb3JpZW50YXRpb24ueiwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLnVwWC5zZXRWYWx1ZUF0VGltZSggdXAueCwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLnVwWS5zZXRWYWx1ZUF0VGltZSggdXAueSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cdFx0XHRcdGxpc3RlbmVyLnVwWi5zZXRWYWx1ZUF0VGltZSggdXAueiwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0bGlzdGVuZXIuc2V0UG9zaXRpb24oIHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHBvc2l0aW9uLnogKTtcblx0XHRcdFx0bGlzdGVuZXIuc2V0T3JpZW50YXRpb24oIG9yaWVudGF0aW9uLngsIG9yaWVudGF0aW9uLnksIG9yaWVudGF0aW9uLnosIHVwLngsIHVwLnksIHVwLnogKTtcblxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHR9ICkoKVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgUmVlY2UgQWFyb24gTGVjcml2YWluIC8gaHR0cDovL3JlZWNlbm90ZXMuY29tL1xuICovXG5cbmZ1bmN0aW9uIEF1ZGlvKCBsaXN0ZW5lciApIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0F1ZGlvJztcblxuXHR0aGlzLmNvbnRleHQgPSBsaXN0ZW5lci5jb250ZXh0O1xuXG5cdHRoaXMuZ2FpbiA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG5cdHRoaXMuZ2Fpbi5jb25uZWN0KCBsaXN0ZW5lci5nZXRJbnB1dCgpICk7XG5cblx0dGhpcy5hdXRvcGxheSA9IGZhbHNlO1xuXG5cdHRoaXMuYnVmZmVyID0gbnVsbDtcblx0dGhpcy5sb29wID0gZmFsc2U7XG5cdHRoaXMuc3RhcnRUaW1lID0gMDtcblx0dGhpcy5wbGF5YmFja1JhdGUgPSAxO1xuXHR0aGlzLmlzUGxheWluZyA9IGZhbHNlO1xuXHR0aGlzLmhhc1BsYXliYWNrQ29udHJvbCA9IHRydWU7XG5cdHRoaXMuc291cmNlVHlwZSA9ICdlbXB0eSc7XG5cblx0dGhpcy5maWx0ZXJzID0gW107XG5cbn1cblxuQXVkaW8ucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogQXVkaW8sXG5cblx0Z2V0T3V0cHV0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5nYWluO1xuXG5cdH0sXG5cblx0c2V0Tm9kZVNvdXJjZTogZnVuY3Rpb24gKCBhdWRpb05vZGUgKSB7XG5cblx0XHR0aGlzLmhhc1BsYXliYWNrQ29udHJvbCA9IGZhbHNlO1xuXHRcdHRoaXMuc291cmNlVHlwZSA9ICdhdWRpb05vZGUnO1xuXHRcdHRoaXMuc291cmNlID0gYXVkaW9Ob2RlO1xuXHRcdHRoaXMuY29ubmVjdCgpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRCdWZmZXI6IGZ1bmN0aW9uICggYXVkaW9CdWZmZXIgKSB7XG5cblx0XHR0aGlzLmJ1ZmZlciA9IGF1ZGlvQnVmZmVyO1xuXHRcdHRoaXMuc291cmNlVHlwZSA9ICdidWZmZXInO1xuXG5cdFx0aWYgKCB0aGlzLmF1dG9wbGF5ICkgdGhpcy5wbGF5KCk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHBsYXk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGlmICggdGhpcy5pc1BsYXlpbmcgPT09IHRydWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkF1ZGlvOiBBdWRpbyBpcyBhbHJlYWR5IHBsYXlpbmcuJyApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmhhc1BsYXliYWNrQ29udHJvbCA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkF1ZGlvOiB0aGlzIEF1ZGlvIGhhcyBubyBwbGF5YmFjayBjb250cm9sLicgKTtcblx0XHRcdHJldHVybjtcblxuXHRcdH1cblxuXHRcdHZhciBzb3VyY2UgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG5cblx0XHRzb3VyY2UuYnVmZmVyID0gdGhpcy5idWZmZXI7XG5cdFx0c291cmNlLmxvb3AgPSB0aGlzLmxvb3A7XG5cdFx0c291cmNlLm9uZW5kZWQgPSB0aGlzLm9uRW5kZWQuYmluZCggdGhpcyApO1xuXHRcdHNvdXJjZS5wbGF5YmFja1JhdGUuc2V0VmFsdWVBdFRpbWUoIHRoaXMucGxheWJhY2tSYXRlLCB0aGlzLnN0YXJ0VGltZSApO1xuXHRcdHNvdXJjZS5zdGFydCggMCwgdGhpcy5zdGFydFRpbWUgKTtcblxuXHRcdHRoaXMuaXNQbGF5aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMuc291cmNlID0gc291cmNlO1xuXG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdCgpO1xuXG5cdH0sXG5cblx0cGF1c2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGlmICggdGhpcy5oYXNQbGF5YmFja0NvbnRyb2wgPT09IGZhbHNlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5BdWRpbzogdGhpcyBBdWRpbyBoYXMgbm8gcGxheWJhY2sgY29udHJvbC4nICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHR0aGlzLnNvdXJjZS5zdG9wKCk7XG5cdFx0dGhpcy5zdGFydFRpbWUgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG5cdFx0dGhpcy5pc1BsYXlpbmcgPSBmYWxzZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c3RvcDogZnVuY3Rpb24gKCkge1xuXG5cdFx0aWYgKCB0aGlzLmhhc1BsYXliYWNrQ29udHJvbCA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkF1ZGlvOiB0aGlzIEF1ZGlvIGhhcyBubyBwbGF5YmFjayBjb250cm9sLicgKTtcblx0XHRcdHJldHVybjtcblxuXHRcdH1cblxuXHRcdHRoaXMuc291cmNlLnN0b3AoKTtcblx0XHR0aGlzLnN0YXJ0VGltZSA9IDA7XG5cdFx0dGhpcy5pc1BsYXlpbmcgPSBmYWxzZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29ubmVjdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0aWYgKCB0aGlzLmZpbHRlcnMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dGhpcy5zb3VyY2UuY29ubmVjdCggdGhpcy5maWx0ZXJzWyAwIF0gKTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAxLCBsID0gdGhpcy5maWx0ZXJzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dGhpcy5maWx0ZXJzWyBpIC0gMSBdLmNvbm5lY3QoIHRoaXMuZmlsdGVyc1sgaSBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0dGhpcy5maWx0ZXJzWyB0aGlzLmZpbHRlcnMubGVuZ3RoIC0gMSBdLmNvbm5lY3QoIHRoaXMuZ2V0T3V0cHV0KCkgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRoaXMuc291cmNlLmNvbm5lY3QoIHRoaXMuZ2V0T3V0cHV0KCkgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0ZGlzY29ubmVjdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0aWYgKCB0aGlzLmZpbHRlcnMubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0dGhpcy5zb3VyY2UuZGlzY29ubmVjdCggdGhpcy5maWx0ZXJzWyAwIF0gKTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAxLCBsID0gdGhpcy5maWx0ZXJzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dGhpcy5maWx0ZXJzWyBpIC0gMSBdLmRpc2Nvbm5lY3QoIHRoaXMuZmlsdGVyc1sgaSBdICk7XG5cblx0XHRcdH1cblxuXHRcdFx0dGhpcy5maWx0ZXJzWyB0aGlzLmZpbHRlcnMubGVuZ3RoIC0gMSBdLmRpc2Nvbm5lY3QoIHRoaXMuZ2V0T3V0cHV0KCkgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHRoaXMuc291cmNlLmRpc2Nvbm5lY3QoIHRoaXMuZ2V0T3V0cHV0KCkgKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Z2V0RmlsdGVyczogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVycztcblxuXHR9LFxuXG5cdHNldEZpbHRlcnM6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRpZiAoICEgdmFsdWUgKSB2YWx1ZSA9IFtdO1xuXG5cdFx0aWYgKCB0aGlzLmlzUGxheWluZyA9PT0gdHJ1ZSApIHtcblxuXHRcdFx0dGhpcy5kaXNjb25uZWN0KCk7XG5cdFx0XHR0aGlzLmZpbHRlcnMgPSB2YWx1ZTtcblx0XHRcdHRoaXMuY29ubmVjdCgpO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dGhpcy5maWx0ZXJzID0gdmFsdWU7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldEZpbHRlcjogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0RmlsdGVycygpWyAwIF07XG5cblx0fSxcblxuXHRzZXRGaWx0ZXI6IGZ1bmN0aW9uICggZmlsdGVyICkge1xuXG5cdFx0cmV0dXJuIHRoaXMuc2V0RmlsdGVycyggZmlsdGVyID8gWyBmaWx0ZXIgXSA6IFtdICk7XG5cblx0fSxcblxuXHRzZXRQbGF5YmFja1JhdGU6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRpZiAoIHRoaXMuaGFzUGxheWJhY2tDb250cm9sID09PSBmYWxzZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQXVkaW86IHRoaXMgQXVkaW8gaGFzIG5vIHBsYXliYWNrIGNvbnRyb2wuJyApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5wbGF5YmFja1JhdGUgPSB2YWx1ZTtcblxuXHRcdGlmICggdGhpcy5pc1BsYXlpbmcgPT09IHRydWUgKSB7XG5cblx0XHRcdHRoaXMuc291cmNlLnBsYXliYWNrUmF0ZS5zZXRWYWx1ZUF0VGltZSggdGhpcy5wbGF5YmFja1JhdGUsIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRnZXRQbGF5YmFja1JhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnBsYXliYWNrUmF0ZTtcblxuXHR9LFxuXG5cdG9uRW5kZWQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuaXNQbGF5aW5nID0gZmFsc2U7XG5cblx0fSxcblxuXHRnZXRMb29wOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRpZiAoIHRoaXMuaGFzUGxheWJhY2tDb250cm9sID09PSBmYWxzZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQXVkaW86IHRoaXMgQXVkaW8gaGFzIG5vIHBsYXliYWNrIGNvbnRyb2wuJyApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMubG9vcDtcblxuXHR9LFxuXG5cdHNldExvb3A6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRpZiAoIHRoaXMuaGFzUGxheWJhY2tDb250cm9sID09PSBmYWxzZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQXVkaW86IHRoaXMgQXVkaW8gaGFzIG5vIHBsYXliYWNrIGNvbnRyb2wuJyApO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5sb29wID0gdmFsdWU7XG5cblx0XHRpZiAoIHRoaXMuaXNQbGF5aW5nID09PSB0cnVlICkge1xuXG5cdFx0XHR0aGlzLnNvdXJjZS5sb29wID0gdGhpcy5sb29wO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRnZXRWb2x1bWU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLmdhaW4uZ2Fpbi52YWx1ZTtcblxuXHR9LFxuXHRcblx0c2V0Vm9sdW1lOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy5nYWluLmdhaW4udmFsdWUgPSB2YWx1ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gUG9zaXRpb25hbEF1ZGlvKCBsaXN0ZW5lciApIHtcblxuXHRBdWRpby5jYWxsKCB0aGlzLCBsaXN0ZW5lciApO1xuXG5cdHRoaXMucGFubmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuXHR0aGlzLnBhbm5lci5jb25uZWN0KCB0aGlzLmdhaW4gKTtcblxufVxuXG5Qb3NpdGlvbmFsQXVkaW8ucHJvdG90eXBlID0gT2JqZWN0LmFzc2lnbiggT2JqZWN0LmNyZWF0ZSggQXVkaW8ucHJvdG90eXBlICksIHtcblxuXHRjb25zdHJ1Y3RvcjogUG9zaXRpb25hbEF1ZGlvLFxuXG5cdGdldE91dHB1dDogZnVuY3Rpb24gKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMucGFubmVyO1xuXG5cdH0sXG5cblx0Z2V0UmVmRGlzdGFuY2U6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnBhbm5lci5yZWZEaXN0YW5jZTtcblxuXHR9LFxuXG5cdHNldFJlZkRpc3RhbmNlOiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0dGhpcy5wYW5uZXIucmVmRGlzdGFuY2UgPSB2YWx1ZTtcblxuXHR9LFxuXG5cdGdldFJvbGxvZmZGYWN0b3I6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnBhbm5lci5yb2xsb2ZmRmFjdG9yO1xuXG5cdH0sXG5cblx0c2V0Um9sbG9mZkZhY3RvcjogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMucGFubmVyLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcblxuXHR9LFxuXG5cdGdldERpc3RhbmNlTW9kZWw6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiB0aGlzLnBhbm5lci5kaXN0YW5jZU1vZGVsO1xuXG5cdH0sXG5cblx0c2V0RGlzdGFuY2VNb2RlbDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMucGFubmVyLmRpc3RhbmNlTW9kZWwgPSB2YWx1ZTtcblxuXHR9LFxuXG5cdGdldE1heERpc3RhbmNlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5wYW5uZXIubWF4RGlzdGFuY2U7XG5cblx0fSxcblxuXHRzZXRNYXhEaXN0YW5jZTogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdHRoaXMucGFubmVyLm1heERpc3RhbmNlID0gdmFsdWU7XG5cblx0fSxcblxuXHR1cGRhdGVNYXRyaXhXb3JsZDogKCBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcG9zaXRpb24gPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZU1hdHJpeFdvcmxkKCBmb3JjZSApIHtcblxuXHRcdFx0T2JqZWN0M0QucHJvdG90eXBlLnVwZGF0ZU1hdHJpeFdvcmxkLmNhbGwoIHRoaXMsIGZvcmNlICk7XG5cblx0XHRcdHBvc2l0aW9uLnNldEZyb21NYXRyaXhQb3NpdGlvbiggdGhpcy5tYXRyaXhXb3JsZCApO1xuXG5cdFx0XHR0aGlzLnBhbm5lci5zZXRQb3NpdGlvbiggcG9zaXRpb24ueCwgcG9zaXRpb24ueSwgcG9zaXRpb24ueiApO1xuXG5cdFx0fTtcblxuXHR9ICkoKVxuXG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEF1ZGlvQW5hbHlzZXIoIGF1ZGlvLCBmZnRTaXplICkge1xuXG5cdHRoaXMuYW5hbHlzZXIgPSBhdWRpby5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG5cdHRoaXMuYW5hbHlzZXIuZmZ0U2l6ZSA9IGZmdFNpemUgIT09IHVuZGVmaW5lZCA/IGZmdFNpemUgOiAyMDQ4O1xuXG5cdHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KCB0aGlzLmFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50ICk7XG5cblx0YXVkaW8uZ2V0T3V0cHV0KCkuY29ubmVjdCggdGhpcy5hbmFseXNlciApO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIEF1ZGlvQW5hbHlzZXIucHJvdG90eXBlLCB7XG5cblx0Z2V0RnJlcXVlbmN5RGF0YTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5hbmFseXNlci5nZXRCeXRlRnJlcXVlbmN5RGF0YSggdGhpcy5kYXRhICk7XG5cblx0XHRyZXR1cm4gdGhpcy5kYXRhO1xuXG5cdH0sXG5cblx0Z2V0QXZlcmFnZUZyZXF1ZW5jeTogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHZhbHVlID0gMCwgZGF0YSA9IHRoaXMuZ2V0RnJlcXVlbmN5RGF0YSgpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdHZhbHVlICs9IGRhdGFbIGkgXTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB2YWx1ZSAvIGRhdGEubGVuZ3RoO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqXG4gKiBCdWZmZXJlZCBzY2VuZSBncmFwaCBwcm9wZXJ0eSB0aGF0IGFsbG93cyB3ZWlnaHRlZCBhY2N1bXVsYXRpb24uXG4gKlxuICpcbiAqIEBhdXRob3IgQmVuIEhvdXN0b24gLyBodHRwOi8vY2xhcmEuaW8vXG4gKiBAYXV0aG9yIERhdmlkIFNhcm5vIC8gaHR0cDovL2xpZ2h0aGF1cy51cy9cbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBQcm9wZXJ0eU1peGVyKCBiaW5kaW5nLCB0eXBlTmFtZSwgdmFsdWVTaXplICkge1xuXG5cdHRoaXMuYmluZGluZyA9IGJpbmRpbmc7XG5cdHRoaXMudmFsdWVTaXplID0gdmFsdWVTaXplO1xuXG5cdHZhciBidWZmZXJUeXBlID0gRmxvYXQ2NEFycmF5LFxuXHRcdG1peEZ1bmN0aW9uO1xuXG5cdHN3aXRjaCAoIHR5cGVOYW1lICkge1xuXG5cdFx0Y2FzZSAncXVhdGVybmlvbic6XG5cdFx0XHRtaXhGdW5jdGlvbiA9IHRoaXMuX3NsZXJwO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICdzdHJpbmcnOlxuXHRcdGNhc2UgJ2Jvb2wnOlxuXHRcdFx0YnVmZmVyVHlwZSA9IEFycmF5O1xuXHRcdFx0bWl4RnVuY3Rpb24gPSB0aGlzLl9zZWxlY3Q7XG5cdFx0XHRicmVhaztcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHRtaXhGdW5jdGlvbiA9IHRoaXMuX2xlcnA7XG5cblx0fVxuXG5cdHRoaXMuYnVmZmVyID0gbmV3IGJ1ZmZlclR5cGUoIHZhbHVlU2l6ZSAqIDQgKTtcblx0Ly8gbGF5b3V0OiBbIGluY29taW5nIHwgYWNjdTAgfCBhY2N1MSB8IG9yaWcgXVxuXHQvL1xuXHQvLyBpbnRlcnBvbGF0b3JzIGNhbiB1c2UgLmJ1ZmZlciBhcyB0aGVpciAucmVzdWx0XG5cdC8vIHRoZSBkYXRhIHRoZW4gZ29lcyB0byAnaW5jb21pbmcnXG5cdC8vXG5cdC8vICdhY2N1MCcgYW5kICdhY2N1MScgYXJlIHVzZWQgZnJhbWUtaW50ZXJsZWF2ZWQgZm9yXG5cdC8vIHRoZSBjdW11bGF0aXZlIHJlc3VsdCBhbmQgYXJlIGNvbXBhcmVkIHRvIGRldGVjdFxuXHQvLyBjaGFuZ2VzXG5cdC8vXG5cdC8vICdvcmlnJyBzdG9yZXMgdGhlIG9yaWdpbmFsIHN0YXRlIG9mIHRoZSBwcm9wZXJ0eVxuXG5cdHRoaXMuX21peEJ1ZmZlclJlZ2lvbiA9IG1peEZ1bmN0aW9uO1xuXG5cdHRoaXMuY3VtdWxhdGl2ZVdlaWdodCA9IDA7XG5cblx0dGhpcy51c2VDb3VudCA9IDA7XG5cdHRoaXMucmVmZXJlbmNlQ291bnQgPSAwO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIFByb3BlcnR5TWl4ZXIucHJvdG90eXBlLCB7XG5cblx0Ly8gYWNjdW11bGF0ZSBkYXRhIGluIHRoZSAnaW5jb21pbmcnIHJlZ2lvbiBpbnRvICdhY2N1PGk+J1xuXHRhY2N1bXVsYXRlOiBmdW5jdGlvbiAoIGFjY3VJbmRleCwgd2VpZ2h0ICkge1xuXG5cdFx0Ly8gbm90ZTogaGFwcGlseSBhY2N1bXVsYXRpbmcgbm90aGluZyB3aGVuIHdlaWdodCA9IDAsIHRoZSBjYWxsZXIga25vd3Ncblx0XHQvLyB0aGUgd2VpZ2h0IGFuZCBzaG91bGRuJ3QgaGF2ZSBtYWRlIHRoZSBjYWxsIGluIHRoZSBmaXJzdCBwbGFjZVxuXG5cdFx0dmFyIGJ1ZmZlciA9IHRoaXMuYnVmZmVyLFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cdFx0XHRvZmZzZXQgPSBhY2N1SW5kZXggKiBzdHJpZGUgKyBzdHJpZGUsXG5cblx0XHRcdGN1cnJlbnRXZWlnaHQgPSB0aGlzLmN1bXVsYXRpdmVXZWlnaHQ7XG5cblx0XHRpZiAoIGN1cnJlbnRXZWlnaHQgPT09IDAgKSB7XG5cblx0XHRcdC8vIGFjY3VOIDo9IGluY29taW5nICogd2VpZ2h0XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gc3RyaWRlOyArKyBpICkge1xuXG5cdFx0XHRcdGJ1ZmZlclsgb2Zmc2V0ICsgaSBdID0gYnVmZmVyWyBpIF07XG5cblx0XHRcdH1cblxuXHRcdFx0Y3VycmVudFdlaWdodCA9IHdlaWdodDtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIGFjY3VOIDo9IGFjY3VOICsgaW5jb21pbmcgKiB3ZWlnaHRcblxuXHRcdFx0Y3VycmVudFdlaWdodCArPSB3ZWlnaHQ7XG5cdFx0XHR2YXIgbWl4ID0gd2VpZ2h0IC8gY3VycmVudFdlaWdodDtcblx0XHRcdHRoaXMuX21peEJ1ZmZlclJlZ2lvbiggYnVmZmVyLCBvZmZzZXQsIDAsIG1peCwgc3RyaWRlICk7XG5cblx0XHR9XG5cblx0XHR0aGlzLmN1bXVsYXRpdmVXZWlnaHQgPSBjdXJyZW50V2VpZ2h0O1xuXG5cdH0sXG5cblx0Ly8gYXBwbHkgdGhlIHN0YXRlIG9mICdhY2N1PGk+JyB0byB0aGUgYmluZGluZyB3aGVuIGFjY3VzIGRpZmZlclxuXHRhcHBseTogZnVuY3Rpb24gKCBhY2N1SW5kZXggKSB7XG5cblx0XHR2YXIgc3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cdFx0XHRidWZmZXIgPSB0aGlzLmJ1ZmZlcixcblx0XHRcdG9mZnNldCA9IGFjY3VJbmRleCAqIHN0cmlkZSArIHN0cmlkZSxcblxuXHRcdFx0d2VpZ2h0ID0gdGhpcy5jdW11bGF0aXZlV2VpZ2h0LFxuXG5cdFx0XHRiaW5kaW5nID0gdGhpcy5iaW5kaW5nO1xuXG5cdFx0dGhpcy5jdW11bGF0aXZlV2VpZ2h0ID0gMDtcblxuXHRcdGlmICggd2VpZ2h0IDwgMSApIHtcblxuXHRcdFx0Ly8gYWNjdU4gOj0gYWNjdU4gKyBvcmlnaW5hbCAqICggMSAtIGN1bXVsYXRpdmVXZWlnaHQgKVxuXG5cdFx0XHR2YXIgb3JpZ2luYWxWYWx1ZU9mZnNldCA9IHN0cmlkZSAqIDM7XG5cblx0XHRcdHRoaXMuX21peEJ1ZmZlclJlZ2lvbihcblx0XHRcdFx0YnVmZmVyLCBvZmZzZXQsIG9yaWdpbmFsVmFsdWVPZmZzZXQsIDEgLSB3ZWlnaHQsIHN0cmlkZSApO1xuXG5cdFx0fVxuXG5cdFx0Zm9yICggdmFyIGkgPSBzdHJpZGUsIGUgPSBzdHJpZGUgKyBzdHJpZGU7IGkgIT09IGU7ICsrIGkgKSB7XG5cblx0XHRcdGlmICggYnVmZmVyWyBpIF0gIT09IGJ1ZmZlclsgaSArIHN0cmlkZSBdICkge1xuXG5cdFx0XHRcdC8vIHZhbHVlIGhhcyBjaGFuZ2VkIC0+IHVwZGF0ZSBzY2VuZSBncmFwaFxuXG5cdFx0XHRcdGJpbmRpbmcuc2V0VmFsdWUoIGJ1ZmZlciwgb2Zmc2V0ICk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fSxcblxuXHQvLyByZW1lbWJlciB0aGUgc3RhdGUgb2YgdGhlIGJvdW5kIHByb3BlcnR5IGFuZCBjb3B5IGl0IHRvIGJvdGggYWNjdXNcblx0c2F2ZU9yaWdpbmFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBiaW5kaW5nID0gdGhpcy5iaW5kaW5nO1xuXG5cdFx0dmFyIGJ1ZmZlciA9IHRoaXMuYnVmZmVyLFxuXHRcdFx0c3RyaWRlID0gdGhpcy52YWx1ZVNpemUsXG5cblx0XHRcdG9yaWdpbmFsVmFsdWVPZmZzZXQgPSBzdHJpZGUgKiAzO1xuXG5cdFx0YmluZGluZy5nZXRWYWx1ZSggYnVmZmVyLCBvcmlnaW5hbFZhbHVlT2Zmc2V0ICk7XG5cblx0XHQvLyBhY2N1WzAuLjFdIDo9IG9yaWcgLS0gaW5pdGlhbGx5IGRldGVjdCBjaGFuZ2VzIGFnYWluc3QgdGhlIG9yaWdpbmFsXG5cdFx0Zm9yICggdmFyIGkgPSBzdHJpZGUsIGUgPSBvcmlnaW5hbFZhbHVlT2Zmc2V0OyBpICE9PSBlOyArKyBpICkge1xuXG5cdFx0XHRidWZmZXJbIGkgXSA9IGJ1ZmZlclsgb3JpZ2luYWxWYWx1ZU9mZnNldCArICggaSAlIHN0cmlkZSApIF07XG5cblx0XHR9XG5cblx0XHR0aGlzLmN1bXVsYXRpdmVXZWlnaHQgPSAwO1xuXG5cdH0sXG5cblx0Ly8gYXBwbHkgdGhlIHN0YXRlIHByZXZpb3VzbHkgdGFrZW4gdmlhICdzYXZlT3JpZ2luYWxTdGF0ZScgdG8gdGhlIGJpbmRpbmdcblx0cmVzdG9yZU9yaWdpbmFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBvcmlnaW5hbFZhbHVlT2Zmc2V0ID0gdGhpcy52YWx1ZVNpemUgKiAzO1xuXHRcdHRoaXMuYmluZGluZy5zZXRWYWx1ZSggdGhpcy5idWZmZXIsIG9yaWdpbmFsVmFsdWVPZmZzZXQgKTtcblxuXHR9LFxuXG5cblx0Ly8gbWl4IGZ1bmN0aW9uc1xuXG5cdF9zZWxlY3Q6IGZ1bmN0aW9uICggYnVmZmVyLCBkc3RPZmZzZXQsIHNyY09mZnNldCwgdCwgc3RyaWRlICkge1xuXG5cdFx0aWYgKCB0ID49IDAuNSApIHtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBzdHJpZGU7ICsrIGkgKSB7XG5cblx0XHRcdFx0YnVmZmVyWyBkc3RPZmZzZXQgKyBpIF0gPSBidWZmZXJbIHNyY09mZnNldCArIGkgXTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0X3NsZXJwOiBmdW5jdGlvbiAoIGJ1ZmZlciwgZHN0T2Zmc2V0LCBzcmNPZmZzZXQsIHQgKSB7XG5cblx0XHRRdWF0ZXJuaW9uLnNsZXJwRmxhdCggYnVmZmVyLCBkc3RPZmZzZXQsIGJ1ZmZlciwgZHN0T2Zmc2V0LCBidWZmZXIsIHNyY09mZnNldCwgdCApO1xuXG5cdH0sXG5cblx0X2xlcnA6IGZ1bmN0aW9uICggYnVmZmVyLCBkc3RPZmZzZXQsIHNyY09mZnNldCwgdCwgc3RyaWRlICkge1xuXG5cdFx0dmFyIHMgPSAxIC0gdDtcblxuXHRcdGZvciAoIHZhciBpID0gMDsgaSAhPT0gc3RyaWRlOyArKyBpICkge1xuXG5cdFx0XHR2YXIgaiA9IGRzdE9mZnNldCArIGk7XG5cblx0XHRcdGJ1ZmZlclsgaiBdID0gYnVmZmVyWyBqIF0gKiBzICsgYnVmZmVyWyBzcmNPZmZzZXQgKyBpIF0gKiB0O1xuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG4vKipcbiAqXG4gKiBBIHJlZmVyZW5jZSB0byBhIHJlYWwgcHJvcGVydHkgaW4gdGhlIHNjZW5lIGdyYXBoLlxuICpcbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gQ29tcG9zaXRlKCB0YXJnZXRHcm91cCwgcGF0aCwgb3B0aW9uYWxQYXJzZWRQYXRoICkge1xuXG5cdHZhciBwYXJzZWRQYXRoID0gb3B0aW9uYWxQYXJzZWRQYXRoIHx8IFByb3BlcnR5QmluZGluZy5wYXJzZVRyYWNrTmFtZSggcGF0aCApO1xuXG5cdHRoaXMuX3RhcmdldEdyb3VwID0gdGFyZ2V0R3JvdXA7XG5cdHRoaXMuX2JpbmRpbmdzID0gdGFyZ2V0R3JvdXAuc3Vic2NyaWJlXyggcGF0aCwgcGFyc2VkUGF0aCApO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIENvbXBvc2l0ZS5wcm90b3R5cGUsIHtcblxuXHRnZXRWYWx1ZTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0dGhpcy5iaW5kKCk7IC8vIGJpbmQgYWxsIGJpbmRpbmdcblxuXHRcdHZhciBmaXJzdFZhbGlkSW5kZXggPSB0aGlzLl90YXJnZXRHcm91cC5uQ2FjaGVkT2JqZWN0c18sXG5cdFx0XHRiaW5kaW5nID0gdGhpcy5fYmluZGluZ3NbIGZpcnN0VmFsaWRJbmRleCBdO1xuXG5cdFx0Ly8gYW5kIG9ubHkgY2FsbCAuZ2V0VmFsdWUgb24gdGhlIGZpcnN0XG5cdFx0aWYgKCBiaW5kaW5nICE9PSB1bmRlZmluZWQgKSBiaW5kaW5nLmdldFZhbHVlKCBhcnJheSwgb2Zmc2V0ICk7XG5cblx0fSxcblxuXHRzZXRWYWx1ZTogZnVuY3Rpb24gKCBhcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0dmFyIGJpbmRpbmdzID0gdGhpcy5fYmluZGluZ3M7XG5cblx0XHRmb3IgKCB2YXIgaSA9IHRoaXMuX3RhcmdldEdyb3VwLm5DYWNoZWRPYmplY3RzXyxcblx0XHRcdFx0ICBuID0gYmluZGluZ3MubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHRiaW5kaW5nc1sgaSBdLnNldFZhbHVlKCBhcnJheSwgb2Zmc2V0ICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRiaW5kOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5ncztcblxuXHRcdGZvciAoIHZhciBpID0gdGhpcy5fdGFyZ2V0R3JvdXAubkNhY2hlZE9iamVjdHNfLFxuXHRcdFx0XHQgIG4gPSBiaW5kaW5ncy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdGJpbmRpbmdzWyBpIF0uYmluZCgpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0dW5iaW5kOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5ncztcblxuXHRcdGZvciAoIHZhciBpID0gdGhpcy5fdGFyZ2V0R3JvdXAubkNhY2hlZE9iamVjdHNfLFxuXHRcdFx0XHQgIG4gPSBiaW5kaW5ncy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdGJpbmRpbmdzWyBpIF0udW5iaW5kKCk7XG5cblx0XHR9XG5cblx0fVxuXG59ICk7XG5cblxuZnVuY3Rpb24gUHJvcGVydHlCaW5kaW5nKCByb290Tm9kZSwgcGF0aCwgcGFyc2VkUGF0aCApIHtcblxuXHR0aGlzLnBhdGggPSBwYXRoO1xuXHR0aGlzLnBhcnNlZFBhdGggPSBwYXJzZWRQYXRoIHx8IFByb3BlcnR5QmluZGluZy5wYXJzZVRyYWNrTmFtZSggcGF0aCApO1xuXG5cdHRoaXMubm9kZSA9IFByb3BlcnR5QmluZGluZy5maW5kTm9kZSggcm9vdE5vZGUsIHRoaXMucGFyc2VkUGF0aC5ub2RlTmFtZSApIHx8IHJvb3ROb2RlO1xuXG5cdHRoaXMucm9vdE5vZGUgPSByb290Tm9kZTtcblxufVxuXG5PYmplY3QuYXNzaWduKCBQcm9wZXJ0eUJpbmRpbmcsIHtcblxuXHRDb21wb3NpdGU6IENvbXBvc2l0ZSxcblxuXHRjcmVhdGU6IGZ1bmN0aW9uICggcm9vdCwgcGF0aCwgcGFyc2VkUGF0aCApIHtcblxuXHRcdGlmICggISAoIHJvb3QgJiYgcm9vdC5pc0FuaW1hdGlvbk9iamVjdEdyb3VwICkgKSB7XG5cblx0XHRcdHJldHVybiBuZXcgUHJvcGVydHlCaW5kaW5nKCByb290LCBwYXRoLCBwYXJzZWRQYXRoICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRyZXR1cm4gbmV3IFByb3BlcnR5QmluZGluZy5Db21wb3NpdGUoIHJvb3QsIHBhdGgsIHBhcnNlZFBhdGggKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdHBhcnNlVHJhY2tOYW1lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHQvLyBQYXJlbnQgZGlyZWN0b3JpZXMsIGRlbGltaXRlZCBieSAnLycgb3IgJzonLiBDdXJyZW50bHkgdW51c2VkLCBidXQgbXVzdFxuXHRcdC8vIGJlIG1hdGNoZWQgdG8gcGFyc2UgdGhlIHJlc3Qgb2YgdGhlIHRyYWNrIG5hbWUuXG5cdFx0dmFyIGRpcmVjdG9yeVJlID0gLygoPzpbXFx3LV0rW1xcLzpdKSopLztcblxuXHRcdC8vIFRhcmdldCBub2RlLiBNYXkgY29udGFpbiB3b3JkIGNoYXJhY3RlcnMgKGEtekEtWjAtOV8pIGFuZCAnLicgb3IgJy0nLlxuXHRcdHZhciBub2RlUmUgPSAvKFtcXHctXFwuXSspPy87XG5cblx0XHQvLyBPYmplY3Qgb24gdGFyZ2V0IG5vZGUsIGFuZCBhY2Nlc3Nvci4gTmFtZSBtYXkgY29udGFpbiBvbmx5IHdvcmRcblx0XHQvLyBjaGFyYWN0ZXJzLiBBY2Nlc3NvciBtYXkgY29udGFpbiBhbnkgY2hhcmFjdGVyIGV4Y2VwdCBjbG9zaW5nIGJyYWNrZXQuXG5cdFx0dmFyIG9iamVjdFJlID0gLyg/OlxcLihbXFx3LV0rKSg/OlxcWyguKylcXF0pPyk/LztcblxuXHRcdC8vIFByb3BlcnR5IGFuZCBhY2Nlc3Nvci4gTWF5IGNvbnRhaW4gb25seSB3b3JkIGNoYXJhY3RlcnMuIEFjY2Vzc29yIG1heVxuXHRcdC8vIGNvbnRhaW4gYW55IG5vbi1icmFja2V0IGNoYXJhY3RlcnMuXG5cdFx0dmFyIHByb3BlcnR5UmUgPSAvXFwuKFtcXHctXSspKD86XFxbKC4rKVxcXSk/LztcblxuXHRcdHZhciB0cmFja1JlID0gbmV3IFJlZ0V4cCgnJ1xuXHRcdFx0KyAnXidcblx0XHRcdCsgZGlyZWN0b3J5UmUuc291cmNlXG5cdFx0XHQrIG5vZGVSZS5zb3VyY2Vcblx0XHRcdCsgb2JqZWN0UmUuc291cmNlXG5cdFx0XHQrIHByb3BlcnR5UmUuc291cmNlXG5cdFx0XHQrICckJ1xuXHRcdCk7XG5cblx0XHR2YXIgc3VwcG9ydGVkT2JqZWN0TmFtZXMgPSBbICdtYXRlcmlhbCcsICdtYXRlcmlhbHMnLCAnYm9uZXMnIF07XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gKCB0cmFja05hbWUgKSB7XG5cblx0XHRcdFx0dmFyIG1hdGNoZXMgPSB0cmFja1JlLmV4ZWMoIHRyYWNrTmFtZSApO1xuXG5cdFx0XHRcdGlmICggISBtYXRjaGVzICkge1xuXG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCAnUHJvcGVydHlCaW5kaW5nOiBDYW5ub3QgcGFyc2UgdHJhY2tOYW1lOiAnICsgdHJhY2tOYW1lICk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciByZXN1bHRzID0ge1xuXHRcdFx0XHRcdC8vIGRpcmVjdG9yeU5hbWU6IG1hdGNoZXNbIDEgXSwgLy8gKHRzY2h3KSBjdXJyZW50bHkgdW51c2VkXG5cdFx0XHRcdFx0bm9kZU5hbWU6IG1hdGNoZXNbIDIgXSxcblx0XHRcdFx0XHRvYmplY3ROYW1lOiBtYXRjaGVzWyAzIF0sXG5cdFx0XHRcdFx0b2JqZWN0SW5kZXg6IG1hdGNoZXNbIDQgXSxcblx0XHRcdFx0XHRwcm9wZXJ0eU5hbWU6IG1hdGNoZXNbIDUgXSwgICAgIC8vIHJlcXVpcmVkXG5cdFx0XHRcdFx0cHJvcGVydHlJbmRleDogbWF0Y2hlc1sgNiBdXG5cdFx0XHRcdH07XG5cblx0XHRcdFx0dmFyIGxhc3REb3QgPSByZXN1bHRzLm5vZGVOYW1lICYmIHJlc3VsdHMubm9kZU5hbWUubGFzdEluZGV4T2YoICcuJyApO1xuXG5cdFx0XHRcdGlmICggbGFzdERvdCAhPT0gdW5kZWZpbmVkICYmIGxhc3REb3QgIT09IC0xICkge1xuXG5cdFx0XHRcdFx0dmFyIG9iamVjdE5hbWUgPSByZXN1bHRzLm5vZGVOYW1lLnN1YnN0cmluZyggbGFzdERvdCArIDEgKTtcblxuXHRcdFx0XHRcdC8vIE9iamVjdCBuYW1lcyBtdXN0IGJlIGNoZWNrZWQgYWdhaW5zdCBhIHdoaXRlbGlzdC4gT3RoZXJ3aXNlLCB0aGVyZVxuXHRcdFx0XHRcdC8vIGlzIG5vIHdheSB0byBwYXJzZSAnZm9vLmJhci5iYXonOiAnYmF6JyBtdXN0IGJlIGEgcHJvcGVydHksIGJ1dFxuXHRcdFx0XHRcdC8vICdiYXInIGNvdWxkIGJlIHRoZSBvYmplY3ROYW1lLCBvciBwYXJ0IG9mIGEgbm9kZU5hbWUgKHdoaWNoIGNhblxuXHRcdFx0XHRcdC8vIGluY2x1ZGUgJy4nIGNoYXJhY3RlcnMpLlxuXHRcdFx0XHRcdGlmICggc3VwcG9ydGVkT2JqZWN0TmFtZXMuaW5kZXhPZiggb2JqZWN0TmFtZSApICE9PSAtMSApIHtcblxuXHRcdFx0XHRcdFx0cmVzdWx0cy5ub2RlTmFtZSA9IHJlc3VsdHMubm9kZU5hbWUuc3Vic3RyaW5nKCAwLCBsYXN0RG90ICk7XG5cdFx0XHRcdFx0XHRyZXN1bHRzLm9iamVjdE5hbWUgPSBvYmplY3ROYW1lO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHJlc3VsdHMucHJvcGVydHlOYW1lID09PSBudWxsIHx8IHJlc3VsdHMucHJvcGVydHlOYW1lLmxlbmd0aCA9PT0gMCApIHtcblxuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggJ1Byb3BlcnR5QmluZGluZzogY2FuIG5vdCBwYXJzZSBwcm9wZXJ0eU5hbWUgZnJvbSB0cmFja05hbWU6ICcgKyB0cmFja05hbWUgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdH07XG5cblx0fSgpLFxuXG5cdGZpbmROb2RlOiBmdW5jdGlvbiAoIHJvb3QsIG5vZGVOYW1lICkge1xuXG5cdFx0aWYgKCAhIG5vZGVOYW1lIHx8IG5vZGVOYW1lID09PSBcIlwiIHx8IG5vZGVOYW1lID09PSBcInJvb3RcIiB8fCBub2RlTmFtZSA9PT0gXCIuXCIgfHwgbm9kZU5hbWUgPT09IC0gMSB8fCBub2RlTmFtZSA9PT0gcm9vdC5uYW1lIHx8IG5vZGVOYW1lID09PSByb290LnV1aWQgKSB7XG5cblx0XHRcdHJldHVybiByb290O1xuXG5cdFx0fVxuXG5cdFx0Ly8gc2VhcmNoIGludG8gc2tlbGV0b24gYm9uZXMuXG5cdFx0aWYgKCByb290LnNrZWxldG9uICkge1xuXG5cdFx0XHR2YXIgc2VhcmNoU2tlbGV0b24gPSBmdW5jdGlvbiAoIHNrZWxldG9uICkge1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHNrZWxldG9uLmJvbmVzLmxlbmd0aDsgaSArKyApIHtcblxuXHRcdFx0XHRcdHZhciBib25lID0gc2tlbGV0b24uYm9uZXNbIGkgXTtcblxuXHRcdFx0XHRcdGlmICggYm9uZS5uYW1lID09PSBub2RlTmFtZSApIHtcblxuXHRcdFx0XHRcdFx0cmV0dXJuIGJvbmU7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBudWxsO1xuXG5cdFx0XHR9O1xuXG5cdFx0XHR2YXIgYm9uZSA9IHNlYXJjaFNrZWxldG9uKCByb290LnNrZWxldG9uICk7XG5cblx0XHRcdGlmICggYm9uZSApIHtcblxuXHRcdFx0XHRyZXR1cm4gYm9uZTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gc2VhcmNoIGludG8gbm9kZSBzdWJ0cmVlLlxuXHRcdGlmICggcm9vdC5jaGlsZHJlbiApIHtcblxuXHRcdFx0dmFyIHNlYXJjaE5vZGVTdWJ0cmVlID0gZnVuY3Rpb24gKCBjaGlsZHJlbiApIHtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0XHR2YXIgY2hpbGROb2RlID0gY2hpbGRyZW5bIGkgXTtcblxuXHRcdFx0XHRcdGlmICggY2hpbGROb2RlLm5hbWUgPT09IG5vZGVOYW1lIHx8IGNoaWxkTm9kZS51dWlkID09PSBub2RlTmFtZSApIHtcblxuXHRcdFx0XHRcdFx0cmV0dXJuIGNoaWxkTm9kZTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHZhciByZXN1bHQgPSBzZWFyY2hOb2RlU3VidHJlZSggY2hpbGROb2RlLmNoaWxkcmVuICk7XG5cblx0XHRcdFx0XHRpZiAoIHJlc3VsdCApIHJldHVybiByZXN1bHQ7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBudWxsO1xuXG5cdFx0XHR9O1xuXG5cdFx0XHR2YXIgc3ViVHJlZU5vZGUgPSBzZWFyY2hOb2RlU3VidHJlZSggcm9vdC5jaGlsZHJlbiApO1xuXG5cdFx0XHRpZiAoIHN1YlRyZWVOb2RlICkge1xuXG5cdFx0XHRcdHJldHVybiBzdWJUcmVlTm9kZTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIFByb3BlcnR5QmluZGluZy5wcm90b3R5cGUsIHsgLy8gcHJvdG90eXBlLCBjb250aW51ZWRcblxuXHQvLyB0aGVzZSBhcmUgdXNlZCB0byBcImJpbmRcIiBhIG5vbmV4aXN0ZW50IHByb3BlcnR5XG5cdF9nZXRWYWx1ZV91bmF2YWlsYWJsZTogZnVuY3Rpb24gKCkge30sXG5cdF9zZXRWYWx1ZV91bmF2YWlsYWJsZTogZnVuY3Rpb24gKCkge30sXG5cblx0QmluZGluZ1R5cGU6IHtcblx0XHREaXJlY3Q6IDAsXG5cdFx0RW50aXJlQXJyYXk6IDEsXG5cdFx0QXJyYXlFbGVtZW50OiAyLFxuXHRcdEhhc0Zyb21Ub0FycmF5OiAzXG5cdH0sXG5cblx0VmVyc2lvbmluZzoge1xuXHRcdE5vbmU6IDAsXG5cdFx0TmVlZHNVcGRhdGU6IDEsXG5cdFx0TWF0cml4V29ybGROZWVkc1VwZGF0ZTogMlxuXHR9LFxuXG5cdEdldHRlckJ5QmluZGluZ1R5cGU6IFtcblxuXHRcdGZ1bmN0aW9uIGdldFZhbHVlX2RpcmVjdCggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdGJ1ZmZlclsgb2Zmc2V0IF0gPSB0aGlzLm5vZGVbIHRoaXMucHJvcGVydHlOYW1lIF07XG5cblx0XHR9LFxuXG5cdFx0ZnVuY3Rpb24gZ2V0VmFsdWVfYXJyYXkoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHR2YXIgc291cmNlID0gdGhpcy5yZXNvbHZlZFByb3BlcnR5O1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBzb3VyY2UubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHRcdGJ1ZmZlclsgb2Zmc2V0ICsrIF0gPSBzb3VyY2VbIGkgXTtcblxuXHRcdFx0fVxuXG5cdFx0fSxcblxuXHRcdGZ1bmN0aW9uIGdldFZhbHVlX2FycmF5RWxlbWVudCggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdGJ1ZmZlclsgb2Zmc2V0IF0gPSB0aGlzLnJlc29sdmVkUHJvcGVydHlbIHRoaXMucHJvcGVydHlJbmRleCBdO1xuXG5cdFx0fSxcblxuXHRcdGZ1bmN0aW9uIGdldFZhbHVlX3RvQXJyYXkoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHR0aGlzLnJlc29sdmVkUHJvcGVydHkudG9BcnJheSggYnVmZmVyLCBvZmZzZXQgKTtcblxuXHRcdH1cblxuXHRdLFxuXG5cdFNldHRlckJ5QmluZGluZ1R5cGVBbmRWZXJzaW9uaW5nOiBbXG5cblx0XHRbXG5cdFx0XHQvLyBEaXJlY3RcblxuXHRcdFx0ZnVuY3Rpb24gc2V0VmFsdWVfZGlyZWN0KCBidWZmZXIsIG9mZnNldCApIHtcblxuXHRcdFx0XHR0aGlzLm5vZGVbIHRoaXMucHJvcGVydHlOYW1lIF0gPSBidWZmZXJbIG9mZnNldCBdO1xuXG5cdFx0XHR9LFxuXG5cdFx0XHRmdW5jdGlvbiBzZXRWYWx1ZV9kaXJlY3Rfc2V0TmVlZHNVcGRhdGUoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHRcdHRoaXMubm9kZVsgdGhpcy5wcm9wZXJ0eU5hbWUgXSA9IGJ1ZmZlclsgb2Zmc2V0IF07XG5cdFx0XHRcdHRoaXMudGFyZ2V0T2JqZWN0Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fSxcblxuXHRcdFx0ZnVuY3Rpb24gc2V0VmFsdWVfZGlyZWN0X3NldE1hdHJpeFdvcmxkTmVlZHNVcGRhdGUoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHRcdHRoaXMubm9kZVsgdGhpcy5wcm9wZXJ0eU5hbWUgXSA9IGJ1ZmZlclsgb2Zmc2V0IF07XG5cdFx0XHRcdHRoaXMudGFyZ2V0T2JqZWN0Lm1hdHJpeFdvcmxkTmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHR9XG5cblx0XHRdLCBbXG5cblx0XHRcdC8vIEVudGlyZUFycmF5XG5cblx0XHRcdGZ1bmN0aW9uIHNldFZhbHVlX2FycmF5KCBidWZmZXIsIG9mZnNldCApIHtcblxuXHRcdFx0XHR2YXIgZGVzdCA9IHRoaXMucmVzb2x2ZWRQcm9wZXJ0eTtcblxuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBkZXN0Lmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdFx0XHRcdGRlc3RbIGkgXSA9IGJ1ZmZlclsgb2Zmc2V0ICsrIF07XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9LFxuXG5cdFx0XHRmdW5jdGlvbiBzZXRWYWx1ZV9hcnJheV9zZXROZWVkc1VwZGF0ZSggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdFx0dmFyIGRlc3QgPSB0aGlzLnJlc29sdmVkUHJvcGVydHk7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwLCBuID0gZGVzdC5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdFx0XHRkZXN0WyBpIF0gPSBidWZmZXJbIG9mZnNldCArKyBdO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLnRhcmdldE9iamVjdC5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHRcdH0sXG5cblx0XHRcdGZ1bmN0aW9uIHNldFZhbHVlX2FycmF5X3NldE1hdHJpeFdvcmxkTmVlZHNVcGRhdGUoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHRcdHZhciBkZXN0ID0gdGhpcy5yZXNvbHZlZFByb3BlcnR5O1xuXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMCwgbiA9IGRlc3QubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHRcdFx0ZGVzdFsgaSBdID0gYnVmZmVyWyBvZmZzZXQgKysgXTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy50YXJnZXRPYmplY3QubWF0cml4V29ybGROZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHRcdH1cblxuXHRcdF0sIFtcblxuXHRcdFx0Ly8gQXJyYXlFbGVtZW50XG5cblx0XHRcdGZ1bmN0aW9uIHNldFZhbHVlX2FycmF5RWxlbWVudCggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdFx0dGhpcy5yZXNvbHZlZFByb3BlcnR5WyB0aGlzLnByb3BlcnR5SW5kZXggXSA9IGJ1ZmZlclsgb2Zmc2V0IF07XG5cblx0XHRcdH0sXG5cblx0XHRcdGZ1bmN0aW9uIHNldFZhbHVlX2FycmF5RWxlbWVudF9zZXROZWVkc1VwZGF0ZSggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdFx0dGhpcy5yZXNvbHZlZFByb3BlcnR5WyB0aGlzLnByb3BlcnR5SW5kZXggXSA9IGJ1ZmZlclsgb2Zmc2V0IF07XG5cdFx0XHRcdHRoaXMudGFyZ2V0T2JqZWN0Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fSxcblxuXHRcdFx0ZnVuY3Rpb24gc2V0VmFsdWVfYXJyYXlFbGVtZW50X3NldE1hdHJpeFdvcmxkTmVlZHNVcGRhdGUoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHRcdHRoaXMucmVzb2x2ZWRQcm9wZXJ0eVsgdGhpcy5wcm9wZXJ0eUluZGV4IF0gPSBidWZmZXJbIG9mZnNldCBdO1xuXHRcdFx0XHR0aGlzLnRhcmdldE9iamVjdC5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHRcdFx0fVxuXG5cdFx0XSwgW1xuXG5cdFx0XHQvLyBIYXNUb0Zyb21BcnJheVxuXG5cdFx0XHRmdW5jdGlvbiBzZXRWYWx1ZV9mcm9tQXJyYXkoIGJ1ZmZlciwgb2Zmc2V0ICkge1xuXG5cdFx0XHRcdHRoaXMucmVzb2x2ZWRQcm9wZXJ0eS5mcm9tQXJyYXkoIGJ1ZmZlciwgb2Zmc2V0ICk7XG5cblx0XHRcdH0sXG5cblx0XHRcdGZ1bmN0aW9uIHNldFZhbHVlX2Zyb21BcnJheV9zZXROZWVkc1VwZGF0ZSggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdFx0dGhpcy5yZXNvbHZlZFByb3BlcnR5LmZyb21BcnJheSggYnVmZmVyLCBvZmZzZXQgKTtcblx0XHRcdFx0dGhpcy50YXJnZXRPYmplY3QubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0XHR9LFxuXG5cdFx0XHRmdW5jdGlvbiBzZXRWYWx1ZV9mcm9tQXJyYXlfc2V0TWF0cml4V29ybGROZWVkc1VwZGF0ZSggYnVmZmVyLCBvZmZzZXQgKSB7XG5cblx0XHRcdFx0dGhpcy5yZXNvbHZlZFByb3BlcnR5LmZyb21BcnJheSggYnVmZmVyLCBvZmZzZXQgKTtcblx0XHRcdFx0dGhpcy50YXJnZXRPYmplY3QubWF0cml4V29ybGROZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0XHRcdH1cblxuXHRcdF1cblxuXHRdLFxuXG5cdGdldFZhbHVlOiBmdW5jdGlvbiBnZXRWYWx1ZV91bmJvdW5kKCB0YXJnZXRBcnJheSwgb2Zmc2V0ICkge1xuXG5cdFx0dGhpcy5iaW5kKCk7XG5cdFx0dGhpcy5nZXRWYWx1ZSggdGFyZ2V0QXJyYXksIG9mZnNldCApO1xuXG5cdFx0Ly8gTm90ZTogVGhpcyBjbGFzcyB1c2VzIGEgU3RhdGUgcGF0dGVybiBvbiBhIHBlci1tZXRob2QgYmFzaXM6XG5cdFx0Ly8gJ2JpbmQnIHNldHMgJ3RoaXMuZ2V0VmFsdWUnIC8gJ3NldFZhbHVlJyBhbmQgc2hhZG93cyB0aGVcblx0XHQvLyBwcm90b3R5cGUgdmVyc2lvbiBvZiB0aGVzZSBtZXRob2RzIHdpdGggb25lIHRoYXQgcmVwcmVzZW50c1xuXHRcdC8vIHRoZSBib3VuZCBzdGF0ZS4gV2hlbiB0aGUgcHJvcGVydHkgaXMgbm90IGZvdW5kLCB0aGUgbWV0aG9kc1xuXHRcdC8vIGJlY29tZSBuby1vcHMuXG5cblx0fSxcblxuXHRzZXRWYWx1ZTogZnVuY3Rpb24gZ2V0VmFsdWVfdW5ib3VuZCggc291cmNlQXJyYXksIG9mZnNldCApIHtcblxuXHRcdHRoaXMuYmluZCgpO1xuXHRcdHRoaXMuc2V0VmFsdWUoIHNvdXJjZUFycmF5LCBvZmZzZXQgKTtcblxuXHR9LFxuXG5cdC8vIGNyZWF0ZSBnZXR0ZXIgLyBzZXR0ZXIgcGFpciBmb3IgYSBwcm9wZXJ0eSBpbiB0aGUgc2NlbmUgZ3JhcGhcblx0YmluZDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHRhcmdldE9iamVjdCA9IHRoaXMubm9kZSxcblx0XHRcdHBhcnNlZFBhdGggPSB0aGlzLnBhcnNlZFBhdGgsXG5cblx0XHRcdG9iamVjdE5hbWUgPSBwYXJzZWRQYXRoLm9iamVjdE5hbWUsXG5cdFx0XHRwcm9wZXJ0eU5hbWUgPSBwYXJzZWRQYXRoLnByb3BlcnR5TmFtZSxcblx0XHRcdHByb3BlcnR5SW5kZXggPSBwYXJzZWRQYXRoLnByb3BlcnR5SW5kZXg7XG5cblx0XHRpZiAoICEgdGFyZ2V0T2JqZWN0ICkge1xuXG5cdFx0XHR0YXJnZXRPYmplY3QgPSBQcm9wZXJ0eUJpbmRpbmcuZmluZE5vZGUoXG5cdFx0XHRcdFx0dGhpcy5yb290Tm9kZSwgcGFyc2VkUGF0aC5ub2RlTmFtZSApIHx8IHRoaXMucm9vdE5vZGU7XG5cblx0XHRcdHRoaXMubm9kZSA9IHRhcmdldE9iamVjdDtcblxuXHRcdH1cblxuXHRcdC8vIHNldCBmYWlsIHN0YXRlIHNvIHdlIGNhbiBqdXN0ICdyZXR1cm4nIG9uIGVycm9yXG5cdFx0dGhpcy5nZXRWYWx1ZSA9IHRoaXMuX2dldFZhbHVlX3VuYXZhaWxhYmxlO1xuXHRcdHRoaXMuc2V0VmFsdWUgPSB0aGlzLl9zZXRWYWx1ZV91bmF2YWlsYWJsZTtcblxuXHRcdC8vIGVuc3VyZSB0aGVyZSBpcyBhIHZhbHVlIG5vZGVcblx0XHRpZiAoICEgdGFyZ2V0T2JqZWN0ICkge1xuXG5cdFx0XHRjb25zb2xlLmVycm9yKCBcIiAgdHJ5aW5nIHRvIHVwZGF0ZSBub2RlIGZvciB0cmFjazogXCIgKyB0aGlzLnBhdGggKyBcIiBidXQgaXQgd2Fzbid0IGZvdW5kLlwiICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHRpZiAoIG9iamVjdE5hbWUgKSB7XG5cblx0XHRcdHZhciBvYmplY3RJbmRleCA9IHBhcnNlZFBhdGgub2JqZWN0SW5kZXg7XG5cblx0XHRcdC8vIHNwZWNpYWwgY2FzZXMgd2VyZSB3ZSBuZWVkIHRvIHJlYWNoIGRlZXBlciBpbnRvIHRoZSBoaWVyYXJjaHkgdG8gZ2V0IHRoZSBmYWNlIG1hdGVyaWFscy4uLi5cblx0XHRcdHN3aXRjaCAoIG9iamVjdE5hbWUgKSB7XG5cblx0XHRcdFx0Y2FzZSAnbWF0ZXJpYWxzJzpcblxuXHRcdFx0XHRcdGlmICggISB0YXJnZXRPYmplY3QubWF0ZXJpYWwgKSB7XG5cblx0XHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoICcgIGNhbiBub3QgYmluZCB0byBtYXRlcmlhbCBhcyBub2RlIGRvZXMgbm90IGhhdmUgYSBtYXRlcmlhbCcsIHRoaXMgKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggISB0YXJnZXRPYmplY3QubWF0ZXJpYWwubWF0ZXJpYWxzICkge1xuXG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnICBjYW4gbm90IGJpbmQgdG8gbWF0ZXJpYWwubWF0ZXJpYWxzIGFzIG5vZGUubWF0ZXJpYWwgZG9lcyBub3QgaGF2ZSBhIG1hdGVyaWFscyBhcnJheScsIHRoaXMgKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHRhcmdldE9iamVjdCA9IHRhcmdldE9iamVjdC5tYXRlcmlhbC5tYXRlcmlhbHM7XG5cblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdib25lcyc6XG5cblx0XHRcdFx0XHRpZiAoICEgdGFyZ2V0T2JqZWN0LnNrZWxldG9uICkge1xuXG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCAnICBjYW4gbm90IGJpbmQgdG8gYm9uZXMgYXMgbm9kZSBkb2VzIG5vdCBoYXZlIGEgc2tlbGV0b24nLCB0aGlzICk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBwb3RlbnRpYWwgZnV0dXJlIG9wdGltaXphdGlvbjogc2tpcCB0aGlzIGlmIHByb3BlcnR5SW5kZXggaXMgYWxyZWFkeSBhbiBpbnRlZ2VyXG5cdFx0XHRcdFx0Ly8gYW5kIGNvbnZlcnQgdGhlIGludGVnZXIgc3RyaW5nIHRvIGEgdHJ1ZSBpbnRlZ2VyLlxuXG5cdFx0XHRcdFx0dGFyZ2V0T2JqZWN0ID0gdGFyZ2V0T2JqZWN0LnNrZWxldG9uLmJvbmVzO1xuXG5cdFx0XHRcdFx0Ly8gc3VwcG9ydCByZXNvbHZpbmcgbW9ycGhUYXJnZXQgbmFtZXMgaW50byBpbmRpY2VzLlxuXHRcdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHRhcmdldE9iamVjdC5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRcdGlmICggdGFyZ2V0T2JqZWN0WyBpIF0ubmFtZSA9PT0gb2JqZWN0SW5kZXggKSB7XG5cblx0XHRcdFx0XHRcdFx0b2JqZWN0SW5kZXggPSBpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0ZGVmYXVsdDpcblxuXHRcdFx0XHRcdGlmICggdGFyZ2V0T2JqZWN0WyBvYmplY3ROYW1lIF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdFx0Y29uc29sZS5lcnJvciggJyAgY2FuIG5vdCBiaW5kIHRvIG9iamVjdE5hbWUgb2Ygbm9kZSwgdW5kZWZpbmVkJywgdGhpcyApO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGFyZ2V0T2JqZWN0ID0gdGFyZ2V0T2JqZWN0WyBvYmplY3ROYW1lIF07XG5cblx0XHRcdH1cblxuXG5cdFx0XHRpZiAoIG9iamVjdEluZGV4ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0aWYgKCB0YXJnZXRPYmplY3RbIG9iamVjdEluZGV4IF0gPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoIFwiICB0cnlpbmcgdG8gYmluZCB0byBvYmplY3RJbmRleCBvZiBvYmplY3ROYW1lLCBidXQgaXMgdW5kZWZpbmVkOlwiLCB0aGlzLCB0YXJnZXRPYmplY3QgKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRhcmdldE9iamVjdCA9IHRhcmdldE9iamVjdFsgb2JqZWN0SW5kZXggXTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gcmVzb2x2ZSBwcm9wZXJ0eVxuXHRcdHZhciBub2RlUHJvcGVydHkgPSB0YXJnZXRPYmplY3RbIHByb3BlcnR5TmFtZSBdO1xuXG5cdFx0aWYgKCBub2RlUHJvcGVydHkgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0dmFyIG5vZGVOYW1lID0gcGFyc2VkUGF0aC5ub2RlTmFtZTtcblxuXHRcdFx0Y29uc29sZS5lcnJvciggXCIgIHRyeWluZyB0byB1cGRhdGUgcHJvcGVydHkgZm9yIHRyYWNrOiBcIiArIG5vZGVOYW1lICtcblx0XHRcdFx0Jy4nICsgcHJvcGVydHlOYW1lICsgXCIgYnV0IGl0IHdhc24ndCBmb3VuZC5cIiwgdGFyZ2V0T2JqZWN0ICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHQvLyBkZXRlcm1pbmUgdmVyc2lvbmluZyBzY2hlbWVcblx0XHR2YXIgdmVyc2lvbmluZyA9IHRoaXMuVmVyc2lvbmluZy5Ob25lO1xuXG5cdFx0aWYgKCB0YXJnZXRPYmplY3QubmVlZHNVcGRhdGUgIT09IHVuZGVmaW5lZCApIHsgLy8gbWF0ZXJpYWxcblxuXHRcdFx0dmVyc2lvbmluZyA9IHRoaXMuVmVyc2lvbmluZy5OZWVkc1VwZGF0ZTtcblx0XHRcdHRoaXMudGFyZ2V0T2JqZWN0ID0gdGFyZ2V0T2JqZWN0O1xuXG5cdFx0fSBlbHNlIGlmICggdGFyZ2V0T2JqZWN0Lm1hdHJpeFdvcmxkTmVlZHNVcGRhdGUgIT09IHVuZGVmaW5lZCApIHsgLy8gbm9kZSB0cmFuc2Zvcm1cblxuXHRcdFx0dmVyc2lvbmluZyA9IHRoaXMuVmVyc2lvbmluZy5NYXRyaXhXb3JsZE5lZWRzVXBkYXRlO1xuXHRcdFx0dGhpcy50YXJnZXRPYmplY3QgPSB0YXJnZXRPYmplY3Q7XG5cblx0XHR9XG5cblx0XHQvLyBkZXRlcm1pbmUgaG93IHRoZSBwcm9wZXJ0eSBnZXRzIGJvdW5kXG5cdFx0dmFyIGJpbmRpbmdUeXBlID0gdGhpcy5CaW5kaW5nVHlwZS5EaXJlY3Q7XG5cblx0XHRpZiAoIHByb3BlcnR5SW5kZXggIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gYWNjZXNzIGEgc3ViIGVsZW1lbnQgb2YgdGhlIHByb3BlcnR5IGFycmF5IChvbmx5IHByaW1pdGl2ZXMgYXJlIHN1cHBvcnRlZCByaWdodCBub3cpXG5cblx0XHRcdGlmICggcHJvcGVydHlOYW1lID09PSBcIm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1wiICkge1xuXG5cdFx0XHRcdC8vIHBvdGVudGlhbCBvcHRpbWl6YXRpb24sIHNraXAgdGhpcyBpZiBwcm9wZXJ0eUluZGV4IGlzIGFscmVhZHkgYW4gaW50ZWdlciwgYW5kIGNvbnZlcnQgdGhlIGludGVnZXIgc3RyaW5nIHRvIGEgdHJ1ZSBpbnRlZ2VyLlxuXG5cdFx0XHRcdC8vIHN1cHBvcnQgcmVzb2x2aW5nIG1vcnBoVGFyZ2V0IG5hbWVzIGludG8gaW5kaWNlcy5cblx0XHRcdFx0aWYgKCAhIHRhcmdldE9iamVjdC5nZW9tZXRyeSApIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoICcgIGNhbiBub3QgYmluZCB0byBtb3JwaFRhcmdldEluZmx1ZW5jZXMgYmVjYXN1c2Ugbm9kZSBkb2VzIG5vdCBoYXZlIGEgZ2VvbWV0cnknLCB0aGlzICk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoICEgdGFyZ2V0T2JqZWN0Lmdlb21ldHJ5Lm1vcnBoVGFyZ2V0cyApIHtcblxuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoICcgIGNhbiBub3QgYmluZCB0byBtb3JwaFRhcmdldEluZmx1ZW5jZXMgYmVjYXN1c2Ugbm9kZSBkb2VzIG5vdCBoYXZlIGEgZ2VvbWV0cnkubW9ycGhUYXJnZXRzJywgdGhpcyApO1xuXHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5ub2RlLmdlb21ldHJ5Lm1vcnBoVGFyZ2V0cy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHRcdFx0XHRpZiAoIHRhcmdldE9iamVjdC5nZW9tZXRyeS5tb3JwaFRhcmdldHNbIGkgXS5uYW1lID09PSBwcm9wZXJ0eUluZGV4ICkge1xuXG5cdFx0XHRcdFx0XHRwcm9wZXJ0eUluZGV4ID0gaTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRiaW5kaW5nVHlwZSA9IHRoaXMuQmluZGluZ1R5cGUuQXJyYXlFbGVtZW50O1xuXG5cdFx0XHR0aGlzLnJlc29sdmVkUHJvcGVydHkgPSBub2RlUHJvcGVydHk7XG5cdFx0XHR0aGlzLnByb3BlcnR5SW5kZXggPSBwcm9wZXJ0eUluZGV4O1xuXG5cdFx0fSBlbHNlIGlmICggbm9kZVByb3BlcnR5LmZyb21BcnJheSAhPT0gdW5kZWZpbmVkICYmIG5vZGVQcm9wZXJ0eS50b0FycmF5ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIG11c3QgdXNlIGNvcHkgZm9yIE9iamVjdDNELkV1bGVyL1F1YXRlcm5pb25cblxuXHRcdFx0YmluZGluZ1R5cGUgPSB0aGlzLkJpbmRpbmdUeXBlLkhhc0Zyb21Ub0FycmF5O1xuXG5cdFx0XHR0aGlzLnJlc29sdmVkUHJvcGVydHkgPSBub2RlUHJvcGVydHk7XG5cblx0XHR9IGVsc2UgaWYgKCBBcnJheS5pc0FycmF5KCBub2RlUHJvcGVydHkgKSApIHtcblxuXHRcdFx0YmluZGluZ1R5cGUgPSB0aGlzLkJpbmRpbmdUeXBlLkVudGlyZUFycmF5O1xuXG5cdFx0XHR0aGlzLnJlc29sdmVkUHJvcGVydHkgPSBub2RlUHJvcGVydHk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHR0aGlzLnByb3BlcnR5TmFtZSA9IHByb3BlcnR5TmFtZTtcblxuXHRcdH1cblxuXHRcdC8vIHNlbGVjdCBnZXR0ZXIgLyBzZXR0ZXJcblx0XHR0aGlzLmdldFZhbHVlID0gdGhpcy5HZXR0ZXJCeUJpbmRpbmdUeXBlWyBiaW5kaW5nVHlwZSBdO1xuXHRcdHRoaXMuc2V0VmFsdWUgPSB0aGlzLlNldHRlckJ5QmluZGluZ1R5cGVBbmRWZXJzaW9uaW5nWyBiaW5kaW5nVHlwZSBdWyB2ZXJzaW9uaW5nIF07XG5cblx0fSxcblxuXHR1bmJpbmQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMubm9kZSA9IG51bGw7XG5cblx0XHQvLyBiYWNrIHRvIHRoZSBwcm90b3R5cGUgdmVyc2lvbiBvZiBnZXRWYWx1ZSAvIHNldFZhbHVlXG5cdFx0Ly8gbm90ZTogYXZvaWRpbmcgdG8gbXV0YXRlIHRoZSBzaGFwZSBvZiAndGhpcycgdmlhICdkZWxldGUnXG5cdFx0dGhpcy5nZXRWYWx1ZSA9IHRoaXMuX2dldFZhbHVlX3VuYm91bmQ7XG5cdFx0dGhpcy5zZXRWYWx1ZSA9IHRoaXMuX3NldFZhbHVlX3VuYm91bmQ7XG5cblx0fVxuXG59ICk7XG5cbi8vIVxcIERFQ0xBUkUgQUxJQVMgQUZURVIgYXNzaWduIHByb3RvdHlwZSAhXG5PYmplY3QuYXNzaWduKCBQcm9wZXJ0eUJpbmRpbmcucHJvdG90eXBlLCB7XG5cblx0Ly8gaW5pdGlhbCBzdGF0ZSBvZiB0aGVzZSBtZXRob2RzIHRoYXQgY2FsbHMgJ2JpbmQnXG5cdF9nZXRWYWx1ZV91bmJvdW5kOiBQcm9wZXJ0eUJpbmRpbmcucHJvdG90eXBlLmdldFZhbHVlLFxuXHRfc2V0VmFsdWVfdW5ib3VuZDogUHJvcGVydHlCaW5kaW5nLnByb3RvdHlwZS5zZXRWYWx1ZSxcblxufSApO1xuXG4vKipcbiAqXG4gKiBBIGdyb3VwIG9mIG9iamVjdHMgdGhhdCByZWNlaXZlcyBhIHNoYXJlZCBhbmltYXRpb24gc3RhdGUuXG4gKlxuICogVXNhZ2U6XG4gKlxuICogXHQtXHRBZGQgb2JqZWN0cyB5b3Ugd291bGQgb3RoZXJ3aXNlIHBhc3MgYXMgJ3Jvb3QnIHRvIHRoZVxuICogXHRcdGNvbnN0cnVjdG9yIG9yIHRoZSAuY2xpcEFjdGlvbiBtZXRob2Qgb2YgQW5pbWF0aW9uTWl4ZXIuXG4gKlxuICogXHQtXHRJbnN0ZWFkIHBhc3MgdGhpcyBvYmplY3QgYXMgJ3Jvb3QnLlxuICpcbiAqIFx0LVx0WW91IGNhbiBhbHNvIGFkZCBhbmQgcmVtb3ZlIG9iamVjdHMgbGF0ZXIgd2hlbiB0aGUgbWl4ZXJcbiAqIFx0XHRpcyBydW5uaW5nLlxuICpcbiAqIE5vdGU6XG4gKlxuICogIFx0T2JqZWN0cyBvZiB0aGlzIGNsYXNzIGFwcGVhciBhcyBvbmUgb2JqZWN0IHRvIHRoZSBtaXhlcixcbiAqICBcdHNvIGNhY2hlIGNvbnRyb2wgb2YgdGhlIGluZGl2aWR1YWwgb2JqZWN0cyBtdXN0IGJlIGRvbmVcbiAqICBcdG9uIHRoZSBncm91cC5cbiAqXG4gKiBMaW1pdGF0aW9uOlxuICpcbiAqIFx0LSBcdFRoZSBhbmltYXRlZCBwcm9wZXJ0aWVzIG11c3QgYmUgY29tcGF0aWJsZSBhbW9uZyB0aGVcbiAqIFx0XHRhbGwgb2JqZWN0cyBpbiB0aGUgZ3JvdXAuXG4gKlxuICogIC1cdEEgc2luZ2xlIHByb3BlcnR5IGNhbiBlaXRoZXIgYmUgY29udHJvbGxlZCB0aHJvdWdoIGFcbiAqICBcdHRhcmdldCBncm91cCBvciBkaXJlY3RseSwgYnV0IG5vdCBib3RoLlxuICpcbiAqIEBhdXRob3IgdHNjaHdcbiAqL1xuXG5mdW5jdGlvbiBBbmltYXRpb25PYmplY3RHcm91cCggdmFyX2FyZ3MgKSB7XG5cblx0dGhpcy51dWlkID0gX01hdGguZ2VuZXJhdGVVVUlEKCk7XG5cblx0Ly8gY2FjaGVkIG9iamVjdHMgZm9sbG93ZWQgYnkgdGhlIGFjdGl2ZSBvbmVzXG5cdHRoaXMuX29iamVjdHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggYXJndW1lbnRzICk7XG5cblx0dGhpcy5uQ2FjaGVkT2JqZWN0c18gPSAwO1x0XHRcdC8vIHRocmVzaG9sZFxuXHQvLyBub3RlOiByZWFkIGJ5IFByb3BlcnR5QmluZGluZy5Db21wb3NpdGVcblxuXHR2YXIgaW5kaWNlcyA9IHt9O1xuXHR0aGlzLl9pbmRpY2VzQnlVVUlEID0gaW5kaWNlcztcdFx0Ly8gZm9yIGJvb2trZWVwaW5nXG5cblx0Zm9yICggdmFyIGkgPSAwLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdGluZGljZXNbIGFyZ3VtZW50c1sgaSBdLnV1aWQgXSA9IGk7XG5cblx0fVxuXG5cdHRoaXMuX3BhdGhzID0gW107XHRcdFx0XHRcdC8vIGluc2lkZTogc3RyaW5nXG5cdHRoaXMuX3BhcnNlZFBhdGhzID0gW107XHRcdFx0XHQvLyBpbnNpZGU6IHsgd2UgZG9uJ3QgY2FyZSwgaGVyZSB9XG5cdHRoaXMuX2JpbmRpbmdzID0gW107IFx0XHRcdFx0Ly8gaW5zaWRlOiBBcnJheTwgUHJvcGVydHlCaW5kaW5nID5cblx0dGhpcy5fYmluZGluZ3NJbmRpY2VzQnlQYXRoID0ge307IFx0Ly8gaW5zaWRlOiBpbmRpY2VzIGluIHRoZXNlIGFycmF5c1xuXG5cdHZhciBzY29wZSA9IHRoaXM7XG5cblx0dGhpcy5zdGF0cyA9IHtcblxuXHRcdG9iamVjdHM6IHtcblx0XHRcdGdldCB0b3RhbCgpIHsgcmV0dXJuIHNjb3BlLl9vYmplY3RzLmxlbmd0aDsgfSxcblx0XHRcdGdldCBpblVzZSgpIHsgcmV0dXJuIHRoaXMudG90YWwgLSBzY29wZS5uQ2FjaGVkT2JqZWN0c187IH1cblx0XHR9LFxuXG5cdFx0Z2V0IGJpbmRpbmdzUGVyT2JqZWN0KCkgeyByZXR1cm4gc2NvcGUuX2JpbmRpbmdzLmxlbmd0aDsgfVxuXG5cdH07XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQW5pbWF0aW9uT2JqZWN0R3JvdXAucHJvdG90eXBlLCB7XG5cblx0aXNBbmltYXRpb25PYmplY3RHcm91cDogdHJ1ZSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCB2YXJfYXJncyApIHtcblxuXHRcdHZhciBvYmplY3RzID0gdGhpcy5fb2JqZWN0cyxcblx0XHRcdG5PYmplY3RzID0gb2JqZWN0cy5sZW5ndGgsXG5cdFx0XHRuQ2FjaGVkT2JqZWN0cyA9IHRoaXMubkNhY2hlZE9iamVjdHNfLFxuXHRcdFx0aW5kaWNlc0J5VVVJRCA9IHRoaXMuX2luZGljZXNCeVVVSUQsXG5cdFx0XHRwYXRocyA9IHRoaXMuX3BhdGhzLFxuXHRcdFx0cGFyc2VkUGF0aHMgPSB0aGlzLl9wYXJzZWRQYXRocyxcblx0XHRcdGJpbmRpbmdzID0gdGhpcy5fYmluZGluZ3MsXG5cdFx0XHRuQmluZGluZ3MgPSBiaW5kaW5ncy5sZW5ndGg7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHR2YXIgb2JqZWN0ID0gYXJndW1lbnRzWyBpIF0sXG5cdFx0XHRcdHV1aWQgPSBvYmplY3QudXVpZCxcblx0XHRcdFx0aW5kZXggPSBpbmRpY2VzQnlVVUlEWyB1dWlkIF0sXG5cdFx0XHRcdGtub3duT2JqZWN0ID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRpZiAoIGluZGV4ID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gdW5rbm93biBvYmplY3QgLT4gYWRkIGl0IHRvIHRoZSBBQ1RJVkUgcmVnaW9uXG5cblx0XHRcdFx0aW5kZXggPSBuT2JqZWN0cyArKztcblx0XHRcdFx0aW5kaWNlc0J5VVVJRFsgdXVpZCBdID0gaW5kZXg7XG5cdFx0XHRcdG9iamVjdHMucHVzaCggb2JqZWN0ICk7XG5cblx0XHRcdFx0Ly8gYWNjb3VudGluZyBpcyBkb25lLCBub3cgZG8gdGhlIHNhbWUgZm9yIGFsbCBiaW5kaW5nc1xuXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMCwgbSA9IG5CaW5kaW5nczsgaiAhPT0gbTsgKysgaiApIHtcblxuXHRcdFx0XHRcdGJpbmRpbmdzWyBqIF0ucHVzaChcblx0XHRcdFx0XHRcdFx0bmV3IFByb3BlcnR5QmluZGluZyhcblx0XHRcdFx0XHRcdFx0XHRvYmplY3QsIHBhdGhzWyBqIF0sIHBhcnNlZFBhdGhzWyBqIF0gKSApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIGlmICggaW5kZXggPCBuQ2FjaGVkT2JqZWN0cyApIHtcblxuXHRcdFx0XHRrbm93bk9iamVjdCA9IG9iamVjdHNbIGluZGV4IF07XG5cblx0XHRcdFx0Ly8gbW92ZSBleGlzdGluZyBvYmplY3QgdG8gdGhlIEFDVElWRSByZWdpb25cblxuXHRcdFx0XHR2YXIgZmlyc3RBY3RpdmVJbmRleCA9IC0tIG5DYWNoZWRPYmplY3RzLFxuXHRcdFx0XHRcdGxhc3RDYWNoZWRPYmplY3QgPSBvYmplY3RzWyBmaXJzdEFjdGl2ZUluZGV4IF07XG5cblx0XHRcdFx0aW5kaWNlc0J5VVVJRFsgbGFzdENhY2hlZE9iamVjdC51dWlkIF0gPSBpbmRleDtcblx0XHRcdFx0b2JqZWN0c1sgaW5kZXggXSA9IGxhc3RDYWNoZWRPYmplY3Q7XG5cblx0XHRcdFx0aW5kaWNlc0J5VVVJRFsgdXVpZCBdID0gZmlyc3RBY3RpdmVJbmRleDtcblx0XHRcdFx0b2JqZWN0c1sgZmlyc3RBY3RpdmVJbmRleCBdID0gb2JqZWN0O1xuXG5cdFx0XHRcdC8vIGFjY291bnRpbmcgaXMgZG9uZSwgbm93IGRvIHRoZSBzYW1lIGZvciBhbGwgYmluZGluZ3NcblxuXHRcdFx0XHRmb3IgKCB2YXIgaiA9IDAsIG0gPSBuQmluZGluZ3M7IGogIT09IG07ICsrIGogKSB7XG5cblx0XHRcdFx0XHR2YXIgYmluZGluZ3NGb3JQYXRoID0gYmluZGluZ3NbIGogXSxcblx0XHRcdFx0XHRcdGxhc3RDYWNoZWQgPSBiaW5kaW5nc0ZvclBhdGhbIGZpcnN0QWN0aXZlSW5kZXggXSxcblx0XHRcdFx0XHRcdGJpbmRpbmcgPSBiaW5kaW5nc0ZvclBhdGhbIGluZGV4IF07XG5cblx0XHRcdFx0XHRiaW5kaW5nc0ZvclBhdGhbIGluZGV4IF0gPSBsYXN0Q2FjaGVkO1xuXG5cdFx0XHRcdFx0aWYgKCBiaW5kaW5nID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIHNpbmNlIHdlIGRvIG5vdCBib3RoZXIgdG8gY3JlYXRlIG5ldyBiaW5kaW5nc1xuXHRcdFx0XHRcdFx0Ly8gZm9yIG9iamVjdHMgdGhhdCBhcmUgY2FjaGVkLCB0aGUgYmluZGluZyBtYXlcblx0XHRcdFx0XHRcdC8vIG9yIG1heSBub3QgZXhpc3RcblxuXHRcdFx0XHRcdFx0YmluZGluZyA9IG5ldyBQcm9wZXJ0eUJpbmRpbmcoXG5cdFx0XHRcdFx0XHRcdFx0b2JqZWN0LCBwYXRoc1sgaiBdLCBwYXJzZWRQYXRoc1sgaiBdICk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRiaW5kaW5nc0ZvclBhdGhbIGZpcnN0QWN0aXZlSW5kZXggXSA9IGJpbmRpbmc7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKCBvYmplY3RzWyBpbmRleCBdICE9PSBrbm93bk9iamVjdCApIHtcblxuXHRcdFx0XHRjb25zb2xlLmVycm9yKCBcIkRpZmZlcmVudCBvYmplY3RzIHdpdGggdGhlIHNhbWUgVVVJRCBcIiArXG5cdFx0XHRcdFx0XHRcImRldGVjdGVkLiBDbGVhbiB0aGUgY2FjaGVzIG9yIHJlY3JlYXRlIHlvdXIgXCIgK1xuXHRcdFx0XHRcdFx0XCJpbmZyYXN0cnVjdHVyZSB3aGVuIHJlbG9hZGluZyBzY2VuZXMuLi5cIiApO1xuXG5cdFx0XHR9IC8vIGVsc2UgdGhlIG9iamVjdCBpcyBhbHJlYWR5IHdoZXJlIHdlIHdhbnQgaXQgdG8gYmVcblxuXHRcdH0gLy8gZm9yIGFyZ3VtZW50c1xuXG5cdFx0dGhpcy5uQ2FjaGVkT2JqZWN0c18gPSBuQ2FjaGVkT2JqZWN0cztcblxuXHR9LFxuXG5cdHJlbW92ZTogZnVuY3Rpb24oIHZhcl9hcmdzICkge1xuXG5cdFx0dmFyIG9iamVjdHMgPSB0aGlzLl9vYmplY3RzLFxuXHRcdFx0bkNhY2hlZE9iamVjdHMgPSB0aGlzLm5DYWNoZWRPYmplY3RzXyxcblx0XHRcdGluZGljZXNCeVVVSUQgPSB0aGlzLl9pbmRpY2VzQnlVVUlELFxuXHRcdFx0YmluZGluZ3MgPSB0aGlzLl9iaW5kaW5ncyxcblx0XHRcdG5CaW5kaW5ncyA9IGJpbmRpbmdzLmxlbmd0aDtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdHZhciBvYmplY3QgPSBhcmd1bWVudHNbIGkgXSxcblx0XHRcdFx0dXVpZCA9IG9iamVjdC51dWlkLFxuXHRcdFx0XHRpbmRleCA9IGluZGljZXNCeVVVSURbIHV1aWQgXTtcblxuXHRcdFx0aWYgKCBpbmRleCAhPT0gdW5kZWZpbmVkICYmIGluZGV4ID49IG5DYWNoZWRPYmplY3RzICkge1xuXG5cdFx0XHRcdC8vIG1vdmUgZXhpc3Rpbmcgb2JqZWN0IGludG8gdGhlIENBQ0hFRCByZWdpb25cblxuXHRcdFx0XHR2YXIgbGFzdENhY2hlZEluZGV4ID0gbkNhY2hlZE9iamVjdHMgKyssXG5cdFx0XHRcdFx0Zmlyc3RBY3RpdmVPYmplY3QgPSBvYmplY3RzWyBsYXN0Q2FjaGVkSW5kZXggXTtcblxuXHRcdFx0XHRpbmRpY2VzQnlVVUlEWyBmaXJzdEFjdGl2ZU9iamVjdC51dWlkIF0gPSBpbmRleDtcblx0XHRcdFx0b2JqZWN0c1sgaW5kZXggXSA9IGZpcnN0QWN0aXZlT2JqZWN0O1xuXG5cdFx0XHRcdGluZGljZXNCeVVVSURbIHV1aWQgXSA9IGxhc3RDYWNoZWRJbmRleDtcblx0XHRcdFx0b2JqZWN0c1sgbGFzdENhY2hlZEluZGV4IF0gPSBvYmplY3Q7XG5cblx0XHRcdFx0Ly8gYWNjb3VudGluZyBpcyBkb25lLCBub3cgZG8gdGhlIHNhbWUgZm9yIGFsbCBiaW5kaW5nc1xuXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMCwgbSA9IG5CaW5kaW5nczsgaiAhPT0gbTsgKysgaiApIHtcblxuXHRcdFx0XHRcdHZhciBiaW5kaW5nc0ZvclBhdGggPSBiaW5kaW5nc1sgaiBdLFxuXHRcdFx0XHRcdFx0Zmlyc3RBY3RpdmUgPSBiaW5kaW5nc0ZvclBhdGhbIGxhc3RDYWNoZWRJbmRleCBdLFxuXHRcdFx0XHRcdFx0YmluZGluZyA9IGJpbmRpbmdzRm9yUGF0aFsgaW5kZXggXTtcblxuXHRcdFx0XHRcdGJpbmRpbmdzRm9yUGF0aFsgaW5kZXggXSA9IGZpcnN0QWN0aXZlO1xuXHRcdFx0XHRcdGJpbmRpbmdzRm9yUGF0aFsgbGFzdENhY2hlZEluZGV4IF0gPSBiaW5kaW5nO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fSAvLyBmb3IgYXJndW1lbnRzXG5cblx0XHR0aGlzLm5DYWNoZWRPYmplY3RzXyA9IG5DYWNoZWRPYmplY3RzO1xuXG5cdH0sXG5cblx0Ly8gcmVtb3ZlICYgZm9yZ2V0XG5cdHVuY2FjaGU6IGZ1bmN0aW9uKCB2YXJfYXJncyApIHtcblxuXHRcdHZhciBvYmplY3RzID0gdGhpcy5fb2JqZWN0cyxcblx0XHRcdG5PYmplY3RzID0gb2JqZWN0cy5sZW5ndGgsXG5cdFx0XHRuQ2FjaGVkT2JqZWN0cyA9IHRoaXMubkNhY2hlZE9iamVjdHNfLFxuXHRcdFx0aW5kaWNlc0J5VVVJRCA9IHRoaXMuX2luZGljZXNCeVVVSUQsXG5cdFx0XHRiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdzLFxuXHRcdFx0bkJpbmRpbmdzID0gYmluZGluZ3MubGVuZ3RoO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdFx0dmFyIG9iamVjdCA9IGFyZ3VtZW50c1sgaSBdLFxuXHRcdFx0XHR1dWlkID0gb2JqZWN0LnV1aWQsXG5cdFx0XHRcdGluZGV4ID0gaW5kaWNlc0J5VVVJRFsgdXVpZCBdO1xuXG5cdFx0XHRpZiAoIGluZGV4ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0ZGVsZXRlIGluZGljZXNCeVVVSURbIHV1aWQgXTtcblxuXHRcdFx0XHRpZiAoIGluZGV4IDwgbkNhY2hlZE9iamVjdHMgKSB7XG5cblx0XHRcdFx0XHQvLyBvYmplY3QgaXMgY2FjaGVkLCBzaHJpbmsgdGhlIENBQ0hFRCByZWdpb25cblxuXHRcdFx0XHRcdHZhciBmaXJzdEFjdGl2ZUluZGV4ID0gLS0gbkNhY2hlZE9iamVjdHMsXG5cdFx0XHRcdFx0XHRsYXN0Q2FjaGVkT2JqZWN0ID0gb2JqZWN0c1sgZmlyc3RBY3RpdmVJbmRleCBdLFxuXHRcdFx0XHRcdFx0bGFzdEluZGV4ID0gLS0gbk9iamVjdHMsXG5cdFx0XHRcdFx0XHRsYXN0T2JqZWN0ID0gb2JqZWN0c1sgbGFzdEluZGV4IF07XG5cblx0XHRcdFx0XHQvLyBsYXN0IGNhY2hlZCBvYmplY3QgdGFrZXMgdGhpcyBvYmplY3QncyBwbGFjZVxuXHRcdFx0XHRcdGluZGljZXNCeVVVSURbIGxhc3RDYWNoZWRPYmplY3QudXVpZCBdID0gaW5kZXg7XG5cdFx0XHRcdFx0b2JqZWN0c1sgaW5kZXggXSA9IGxhc3RDYWNoZWRPYmplY3Q7XG5cblx0XHRcdFx0XHQvLyBsYXN0IG9iamVjdCBnb2VzIHRvIHRoZSBhY3RpdmF0ZWQgc2xvdCBhbmQgcG9wXG5cdFx0XHRcdFx0aW5kaWNlc0J5VVVJRFsgbGFzdE9iamVjdC51dWlkIF0gPSBmaXJzdEFjdGl2ZUluZGV4O1xuXHRcdFx0XHRcdG9iamVjdHNbIGZpcnN0QWN0aXZlSW5kZXggXSA9IGxhc3RPYmplY3Q7XG5cdFx0XHRcdFx0b2JqZWN0cy5wb3AoKTtcblxuXHRcdFx0XHRcdC8vIGFjY291bnRpbmcgaXMgZG9uZSwgbm93IGRvIHRoZSBzYW1lIGZvciBhbGwgYmluZGluZ3NcblxuXHRcdFx0XHRcdGZvciAoIHZhciBqID0gMCwgbSA9IG5CaW5kaW5nczsgaiAhPT0gbTsgKysgaiApIHtcblxuXHRcdFx0XHRcdFx0dmFyIGJpbmRpbmdzRm9yUGF0aCA9IGJpbmRpbmdzWyBqIF0sXG5cdFx0XHRcdFx0XHRcdGxhc3RDYWNoZWQgPSBiaW5kaW5nc0ZvclBhdGhbIGZpcnN0QWN0aXZlSW5kZXggXSxcblx0XHRcdFx0XHRcdFx0bGFzdCA9IGJpbmRpbmdzRm9yUGF0aFsgbGFzdEluZGV4IF07XG5cblx0XHRcdFx0XHRcdGJpbmRpbmdzRm9yUGF0aFsgaW5kZXggXSA9IGxhc3RDYWNoZWQ7XG5cdFx0XHRcdFx0XHRiaW5kaW5nc0ZvclBhdGhbIGZpcnN0QWN0aXZlSW5kZXggXSA9IGxhc3Q7XG5cdFx0XHRcdFx0XHRiaW5kaW5nc0ZvclBhdGgucG9wKCk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdC8vIG9iamVjdCBpcyBhY3RpdmUsIGp1c3Qgc3dhcCB3aXRoIHRoZSBsYXN0IGFuZCBwb3BcblxuXHRcdFx0XHRcdHZhciBsYXN0SW5kZXggPSAtLSBuT2JqZWN0cyxcblx0XHRcdFx0XHRcdGxhc3RPYmplY3QgPSBvYmplY3RzWyBsYXN0SW5kZXggXTtcblxuXHRcdFx0XHRcdGluZGljZXNCeVVVSURbIGxhc3RPYmplY3QudXVpZCBdID0gaW5kZXg7XG5cdFx0XHRcdFx0b2JqZWN0c1sgaW5kZXggXSA9IGxhc3RPYmplY3Q7XG5cdFx0XHRcdFx0b2JqZWN0cy5wb3AoKTtcblxuXHRcdFx0XHRcdC8vIGFjY291bnRpbmcgaXMgZG9uZSwgbm93IGRvIHRoZSBzYW1lIGZvciBhbGwgYmluZGluZ3NcblxuXHRcdFx0XHRcdGZvciAoIHZhciBqID0gMCwgbSA9IG5CaW5kaW5nczsgaiAhPT0gbTsgKysgaiApIHtcblxuXHRcdFx0XHRcdFx0dmFyIGJpbmRpbmdzRm9yUGF0aCA9IGJpbmRpbmdzWyBqIF07XG5cblx0XHRcdFx0XHRcdGJpbmRpbmdzRm9yUGF0aFsgaW5kZXggXSA9IGJpbmRpbmdzRm9yUGF0aFsgbGFzdEluZGV4IF07XG5cdFx0XHRcdFx0XHRiaW5kaW5nc0ZvclBhdGgucG9wKCk7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSAvLyBjYWNoZWQgb3IgYWN0aXZlXG5cblx0XHRcdH0gLy8gaWYgb2JqZWN0IGlzIGtub3duXG5cblx0XHR9IC8vIGZvciBhcmd1bWVudHNcblxuXHRcdHRoaXMubkNhY2hlZE9iamVjdHNfID0gbkNhY2hlZE9iamVjdHM7XG5cblx0fSxcblxuXHQvLyBJbnRlcm5hbCBpbnRlcmZhY2UgdXNlZCBieSBiZWZyaWVuZGVkIFByb3BlcnR5QmluZGluZy5Db21wb3NpdGU6XG5cblx0c3Vic2NyaWJlXzogZnVuY3Rpb24gKCBwYXRoLCBwYXJzZWRQYXRoICkge1xuXG5cdFx0Ly8gcmV0dXJucyBhbiBhcnJheSBvZiBiaW5kaW5ncyBmb3IgdGhlIGdpdmVuIHBhdGggdGhhdCBpcyBjaGFuZ2VkXG5cdFx0Ly8gYWNjb3JkaW5nIHRvIHRoZSBjb250YWluZWQgb2JqZWN0cyBpbiB0aGUgZ3JvdXBcblxuXHRcdHZhciBpbmRpY2VzQnlQYXRoID0gdGhpcy5fYmluZGluZ3NJbmRpY2VzQnlQYXRoLFxuXHRcdFx0aW5kZXggPSBpbmRpY2VzQnlQYXRoWyBwYXRoIF0sXG5cdFx0XHRiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdzO1xuXG5cdFx0aWYgKCBpbmRleCAhPT0gdW5kZWZpbmVkICkgcmV0dXJuIGJpbmRpbmdzWyBpbmRleCBdO1xuXG5cdFx0dmFyIHBhdGhzID0gdGhpcy5fcGF0aHMsXG5cdFx0XHRwYXJzZWRQYXRocyA9IHRoaXMuX3BhcnNlZFBhdGhzLFxuXHRcdFx0b2JqZWN0cyA9IHRoaXMuX29iamVjdHMsXG5cdFx0XHRuT2JqZWN0cyA9IG9iamVjdHMubGVuZ3RoLFxuXHRcdFx0bkNhY2hlZE9iamVjdHMgPSB0aGlzLm5DYWNoZWRPYmplY3RzXyxcblx0XHRcdGJpbmRpbmdzRm9yUGF0aCA9IG5ldyBBcnJheSggbk9iamVjdHMgKTtcblxuXHRcdGluZGV4ID0gYmluZGluZ3MubGVuZ3RoO1xuXG5cdFx0aW5kaWNlc0J5UGF0aFsgcGF0aCBdID0gaW5kZXg7XG5cblx0XHRwYXRocy5wdXNoKCBwYXRoICk7XG5cdFx0cGFyc2VkUGF0aHMucHVzaCggcGFyc2VkUGF0aCApO1xuXHRcdGJpbmRpbmdzLnB1c2goIGJpbmRpbmdzRm9yUGF0aCApO1xuXG5cdFx0Zm9yICggdmFyIGkgPSBuQ2FjaGVkT2JqZWN0cywgbiA9IG9iamVjdHMubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHR2YXIgb2JqZWN0ID0gb2JqZWN0c1sgaSBdO1xuXHRcdFx0YmluZGluZ3NGb3JQYXRoWyBpIF0gPSBuZXcgUHJvcGVydHlCaW5kaW5nKCBvYmplY3QsIHBhdGgsIHBhcnNlZFBhdGggKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiBiaW5kaW5nc0ZvclBhdGg7XG5cblx0fSxcblxuXHR1bnN1YnNjcmliZV86IGZ1bmN0aW9uICggcGF0aCApIHtcblxuXHRcdC8vIHRlbGxzIHRoZSBncm91cCB0byBmb3JnZXQgYWJvdXQgYSBwcm9wZXJ0eSBwYXRoIGFuZCBubyBsb25nZXJcblx0XHQvLyB1cGRhdGUgdGhlIGFycmF5IHByZXZpb3VzbHkgb2J0YWluZWQgd2l0aCAnc3Vic2NyaWJlXydcblxuXHRcdHZhciBpbmRpY2VzQnlQYXRoID0gdGhpcy5fYmluZGluZ3NJbmRpY2VzQnlQYXRoLFxuXHRcdFx0aW5kZXggPSBpbmRpY2VzQnlQYXRoWyBwYXRoIF07XG5cblx0XHRpZiAoIGluZGV4ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHZhciBwYXRocyA9IHRoaXMuX3BhdGhzLFxuXHRcdFx0XHRwYXJzZWRQYXRocyA9IHRoaXMuX3BhcnNlZFBhdGhzLFxuXHRcdFx0XHRiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdzLFxuXHRcdFx0XHRsYXN0QmluZGluZ3NJbmRleCA9IGJpbmRpbmdzLmxlbmd0aCAtIDEsXG5cdFx0XHRcdGxhc3RCaW5kaW5ncyA9IGJpbmRpbmdzWyBsYXN0QmluZGluZ3NJbmRleCBdLFxuXHRcdFx0XHRsYXN0QmluZGluZ3NQYXRoID0gcGF0aFsgbGFzdEJpbmRpbmdzSW5kZXggXTtcblxuXHRcdFx0aW5kaWNlc0J5UGF0aFsgbGFzdEJpbmRpbmdzUGF0aCBdID0gaW5kZXg7XG5cblx0XHRcdGJpbmRpbmdzWyBpbmRleCBdID0gbGFzdEJpbmRpbmdzO1xuXHRcdFx0YmluZGluZ3MucG9wKCk7XG5cblx0XHRcdHBhcnNlZFBhdGhzWyBpbmRleCBdID0gcGFyc2VkUGF0aHNbIGxhc3RCaW5kaW5nc0luZGV4IF07XG5cdFx0XHRwYXJzZWRQYXRocy5wb3AoKTtcblxuXHRcdFx0cGF0aHNbIGluZGV4IF0gPSBwYXRoc1sgbGFzdEJpbmRpbmdzSW5kZXggXTtcblx0XHRcdHBhdGhzLnBvcCgpO1xuXG5cdFx0fVxuXG5cdH1cblxufSApO1xuXG4vKipcbiAqXG4gKiBBY3Rpb24gcHJvdmlkZWQgYnkgQW5pbWF0aW9uTWl4ZXIgZm9yIHNjaGVkdWxpbmcgY2xpcCBwbGF5YmFjayBvbiBzcGVjaWZpY1xuICogb2JqZWN0cy5cbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKlxuICovXG5cbmZ1bmN0aW9uIEFuaW1hdGlvbkFjdGlvbiggbWl4ZXIsIGNsaXAsIGxvY2FsUm9vdCApIHtcblxuXHR0aGlzLl9taXhlciA9IG1peGVyO1xuXHR0aGlzLl9jbGlwID0gY2xpcDtcblx0dGhpcy5fbG9jYWxSb290ID0gbG9jYWxSb290IHx8IG51bGw7XG5cblx0dmFyIHRyYWNrcyA9IGNsaXAudHJhY2tzLFxuXHRcdG5UcmFja3MgPSB0cmFja3MubGVuZ3RoLFxuXHRcdGludGVycG9sYW50cyA9IG5ldyBBcnJheSggblRyYWNrcyApO1xuXG5cdHZhciBpbnRlcnBvbGFudFNldHRpbmdzID0ge1xuXHRcdFx0ZW5kaW5nU3RhcnQ6IFx0WmVyb0N1cnZhdHVyZUVuZGluZyxcblx0XHRcdGVuZGluZ0VuZDpcdFx0WmVyb0N1cnZhdHVyZUVuZGluZ1xuXHR9O1xuXG5cdGZvciAoIHZhciBpID0gMDsgaSAhPT0gblRyYWNrczsgKysgaSApIHtcblxuXHRcdHZhciBpbnRlcnBvbGFudCA9IHRyYWNrc1sgaSBdLmNyZWF0ZUludGVycG9sYW50KCBudWxsICk7XG5cdFx0aW50ZXJwb2xhbnRzWyBpIF0gPSBpbnRlcnBvbGFudDtcblx0XHRpbnRlcnBvbGFudC5zZXR0aW5ncyA9IGludGVycG9sYW50U2V0dGluZ3M7XG5cblx0fVxuXG5cdHRoaXMuX2ludGVycG9sYW50U2V0dGluZ3MgPSBpbnRlcnBvbGFudFNldHRpbmdzO1xuXG5cdHRoaXMuX2ludGVycG9sYW50cyA9IGludGVycG9sYW50cztcdC8vIGJvdW5kIGJ5IHRoZSBtaXhlclxuXG5cdC8vIGluc2lkZTogUHJvcGVydHlNaXhlciAobWFuYWdlZCBieSB0aGUgbWl4ZXIpXG5cdHRoaXMuX3Byb3BlcnR5QmluZGluZ3MgPSBuZXcgQXJyYXkoIG5UcmFja3MgKTtcblxuXHR0aGlzLl9jYWNoZUluZGV4ID0gbnVsbDtcdFx0XHQvLyBmb3IgdGhlIG1lbW9yeSBtYW5hZ2VyXG5cdHRoaXMuX2J5Q2xpcENhY2hlSW5kZXggPSBudWxsO1x0XHQvLyBmb3IgdGhlIG1lbW9yeSBtYW5hZ2VyXG5cblx0dGhpcy5fdGltZVNjYWxlSW50ZXJwb2xhbnQgPSBudWxsO1xuXHR0aGlzLl93ZWlnaHRJbnRlcnBvbGFudCA9IG51bGw7XG5cblx0dGhpcy5sb29wID0gTG9vcFJlcGVhdDtcblx0dGhpcy5fbG9vcENvdW50ID0gLTE7XG5cblx0Ly8gZ2xvYmFsIG1peGVyIHRpbWUgd2hlbiB0aGUgYWN0aW9uIGlzIHRvIGJlIHN0YXJ0ZWRcblx0Ly8gaXQncyBzZXQgYmFjayB0byAnbnVsbCcgdXBvbiBzdGFydCBvZiB0aGUgYWN0aW9uXG5cdHRoaXMuX3N0YXJ0VGltZSA9IG51bGw7XG5cblx0Ly8gc2NhbGVkIGxvY2FsIHRpbWUgb2YgdGhlIGFjdGlvblxuXHQvLyBnZXRzIGNsYW1wZWQgb3Igd3JhcHBlZCB0byAwLi5jbGlwLmR1cmF0aW9uIGFjY29yZGluZyB0byBsb29wXG5cdHRoaXMudGltZSA9IDA7XG5cblx0dGhpcy50aW1lU2NhbGUgPSAxO1xuXHR0aGlzLl9lZmZlY3RpdmVUaW1lU2NhbGUgPSAxO1xuXG5cdHRoaXMud2VpZ2h0ID0gMTtcblx0dGhpcy5fZWZmZWN0aXZlV2VpZ2h0ID0gMTtcblxuXHR0aGlzLnJlcGV0aXRpb25zID0gSW5maW5pdHk7IFx0XHQvLyBuby4gb2YgcmVwZXRpdGlvbnMgd2hlbiBsb29waW5nXG5cblx0dGhpcy5wYXVzZWQgPSBmYWxzZTtcdFx0XHRcdC8vIHRydWUgLT4gemVybyBlZmZlY3RpdmUgdGltZSBzY2FsZVxuXHR0aGlzLmVuYWJsZWQgPSB0cnVlO1x0XHRcdFx0Ly8gZmFsc2UgLT4gemVybyBlZmZlY3RpdmUgd2VpZ2h0XG5cblx0dGhpcy5jbGFtcFdoZW5GaW5pc2hlZCBcdD0gZmFsc2U7XHQvLyBrZWVwIGZlZWRpbmcgdGhlIGxhc3QgZnJhbWU/XG5cblx0dGhpcy56ZXJvU2xvcGVBdFN0YXJ0IFx0PSB0cnVlO1x0XHQvLyBmb3Igc21vb3RoIGludGVycG9sYXRpb24gdy9vIHNlcGFyYXRlXG5cdHRoaXMuemVyb1Nsb3BlQXRFbmRcdFx0PSB0cnVlO1x0XHQvLyBjbGlwcyBmb3Igc3RhcnQsIGxvb3AgYW5kIGVuZFxuXG59XG5cbk9iamVjdC5hc3NpZ24oIEFuaW1hdGlvbkFjdGlvbi5wcm90b3R5cGUsIHtcblxuXHQvLyBTdGF0ZSAmIFNjaGVkdWxpbmdcblxuXHRwbGF5OiBmdW5jdGlvbigpIHtcblxuXHRcdHRoaXMuX21peGVyLl9hY3RpdmF0ZUFjdGlvbiggdGhpcyApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzdG9wOiBmdW5jdGlvbigpIHtcblxuXHRcdHRoaXMuX21peGVyLl9kZWFjdGl2YXRlQWN0aW9uKCB0aGlzICk7XG5cblx0XHRyZXR1cm4gdGhpcy5yZXNldCgpO1xuXG5cdH0sXG5cblx0cmVzZXQ6IGZ1bmN0aW9uKCkge1xuXG5cdFx0dGhpcy5wYXVzZWQgPSBmYWxzZTtcblx0XHR0aGlzLmVuYWJsZWQgPSB0cnVlO1xuXG5cdFx0dGhpcy50aW1lID0gMDtcdFx0XHQvLyByZXN0YXJ0IGNsaXBcblx0XHR0aGlzLl9sb29wQ291bnQgPSAtMTtcdC8vIGZvcmdldCBwcmV2aW91cyBsb29wc1xuXHRcdHRoaXMuX3N0YXJ0VGltZSA9IG51bGw7XHQvLyBmb3JnZXQgc2NoZWR1bGluZ1xuXG5cdFx0cmV0dXJuIHRoaXMuc3RvcEZhZGluZygpLnN0b3BXYXJwaW5nKCk7XG5cblx0fSxcblxuXHRpc1J1bm5pbmc6IGZ1bmN0aW9uKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuZW5hYmxlZCAmJiAhIHRoaXMucGF1c2VkICYmIHRoaXMudGltZVNjYWxlICE9PSAwICYmXG5cdFx0XHRcdHRoaXMuX3N0YXJ0VGltZSA9PT0gbnVsbCAmJiB0aGlzLl9taXhlci5faXNBY3RpdmVBY3Rpb24oIHRoaXMgKTtcblxuXHR9LFxuXG5cdC8vIHJldHVybiB0cnVlIHdoZW4gcGxheSBoYXMgYmVlbiBjYWxsZWRcblx0aXNTY2hlZHVsZWQ6IGZ1bmN0aW9uKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuX21peGVyLl9pc0FjdGl2ZUFjdGlvbiggdGhpcyApO1xuXG5cdH0sXG5cblx0c3RhcnRBdDogZnVuY3Rpb24oIHRpbWUgKSB7XG5cblx0XHR0aGlzLl9zdGFydFRpbWUgPSB0aW1lO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRMb29wOiBmdW5jdGlvbiggbW9kZSwgcmVwZXRpdGlvbnMgKSB7XG5cblx0XHR0aGlzLmxvb3AgPSBtb2RlO1xuXHRcdHRoaXMucmVwZXRpdGlvbnMgPSByZXBldGl0aW9ucztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Ly8gV2VpZ2h0XG5cblx0Ly8gc2V0IHRoZSB3ZWlnaHQgc3RvcHBpbmcgYW55IHNjaGVkdWxlZCBmYWRpbmdcblx0Ly8gYWx0aG91Z2ggLmVuYWJsZWQgPSBmYWxzZSB5aWVsZHMgYW4gZWZmZWN0aXZlIHdlaWdodCBvZiB6ZXJvLCB0aGlzXG5cdC8vIG1ldGhvZCBkb2VzICpub3QqIGNoYW5nZSAuZW5hYmxlZCwgYmVjYXVzZSBpdCB3b3VsZCBiZSBjb25mdXNpbmdcblx0c2V0RWZmZWN0aXZlV2VpZ2h0OiBmdW5jdGlvbiggd2VpZ2h0ICkge1xuXG5cdFx0dGhpcy53ZWlnaHQgPSB3ZWlnaHQ7XG5cblx0XHQvLyBub3RlOiBzYW1lIGxvZ2ljIGFzIHdoZW4gdXBkYXRlZCBhdCBydW50aW1lXG5cdFx0dGhpcy5fZWZmZWN0aXZlV2VpZ2h0ID0gdGhpcy5lbmFibGVkID8gd2VpZ2h0IDogMDtcblxuXHRcdHJldHVybiB0aGlzLnN0b3BGYWRpbmcoKTtcblxuXHR9LFxuXG5cdC8vIHJldHVybiB0aGUgd2VpZ2h0IGNvbnNpZGVyaW5nIGZhZGluZyBhbmQgLmVuYWJsZWRcblx0Z2V0RWZmZWN0aXZlV2VpZ2h0OiBmdW5jdGlvbigpIHtcblxuXHRcdHJldHVybiB0aGlzLl9lZmZlY3RpdmVXZWlnaHQ7XG5cblx0fSxcblxuXHRmYWRlSW46IGZ1bmN0aW9uKCBkdXJhdGlvbiApIHtcblxuXHRcdHJldHVybiB0aGlzLl9zY2hlZHVsZUZhZGluZyggZHVyYXRpb24sIDAsIDEgKTtcblxuXHR9LFxuXG5cdGZhZGVPdXQ6IGZ1bmN0aW9uKCBkdXJhdGlvbiApIHtcblxuXHRcdHJldHVybiB0aGlzLl9zY2hlZHVsZUZhZGluZyggZHVyYXRpb24sIDEsIDAgKTtcblxuXHR9LFxuXG5cdGNyb3NzRmFkZUZyb206IGZ1bmN0aW9uKCBmYWRlT3V0QWN0aW9uLCBkdXJhdGlvbiwgd2FycCApIHtcblxuXHRcdGZhZGVPdXRBY3Rpb24uZmFkZU91dCggZHVyYXRpb24gKTtcblx0XHR0aGlzLmZhZGVJbiggZHVyYXRpb24gKTtcblxuXHRcdGlmKCB3YXJwICkge1xuXG5cdFx0XHR2YXIgZmFkZUluRHVyYXRpb24gPSB0aGlzLl9jbGlwLmR1cmF0aW9uLFxuXHRcdFx0XHRmYWRlT3V0RHVyYXRpb24gPSBmYWRlT3V0QWN0aW9uLl9jbGlwLmR1cmF0aW9uLFxuXG5cdFx0XHRcdHN0YXJ0RW5kUmF0aW8gPSBmYWRlT3V0RHVyYXRpb24gLyBmYWRlSW5EdXJhdGlvbixcblx0XHRcdFx0ZW5kU3RhcnRSYXRpbyA9IGZhZGVJbkR1cmF0aW9uIC8gZmFkZU91dER1cmF0aW9uO1xuXG5cdFx0XHRmYWRlT3V0QWN0aW9uLndhcnAoIDEuMCwgc3RhcnRFbmRSYXRpbywgZHVyYXRpb24gKTtcblx0XHRcdHRoaXMud2FycCggZW5kU3RhcnRSYXRpbywgMS4wLCBkdXJhdGlvbiApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRjcm9zc0ZhZGVUbzogZnVuY3Rpb24oIGZhZGVJbkFjdGlvbiwgZHVyYXRpb24sIHdhcnAgKSB7XG5cblx0XHRyZXR1cm4gZmFkZUluQWN0aW9uLmNyb3NzRmFkZUZyb20oIHRoaXMsIGR1cmF0aW9uLCB3YXJwICk7XG5cblx0fSxcblxuXHRzdG9wRmFkaW5nOiBmdW5jdGlvbigpIHtcblxuXHRcdHZhciB3ZWlnaHRJbnRlcnBvbGFudCA9IHRoaXMuX3dlaWdodEludGVycG9sYW50O1xuXG5cdFx0aWYgKCB3ZWlnaHRJbnRlcnBvbGFudCAhPT0gbnVsbCApIHtcblxuXHRcdFx0dGhpcy5fd2VpZ2h0SW50ZXJwb2xhbnQgPSBudWxsO1xuXHRcdFx0dGhpcy5fbWl4ZXIuX3Rha2VCYWNrQ29udHJvbEludGVycG9sYW50KCB3ZWlnaHRJbnRlcnBvbGFudCApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHQvLyBUaW1lIFNjYWxlIENvbnRyb2xcblxuXHQvLyBzZXQgdGhlIHRpbWUgc2NhbGUgc3RvcHBpbmcgYW55IHNjaGVkdWxlZCB3YXJwaW5nXG5cdC8vIGFsdGhvdWdoIC5wYXVzZWQgPSB0cnVlIHlpZWxkcyBhbiBlZmZlY3RpdmUgdGltZSBzY2FsZSBvZiB6ZXJvLCB0aGlzXG5cdC8vIG1ldGhvZCBkb2VzICpub3QqIGNoYW5nZSAucGF1c2VkLCBiZWNhdXNlIGl0IHdvdWxkIGJlIGNvbmZ1c2luZ1xuXHRzZXRFZmZlY3RpdmVUaW1lU2NhbGU6IGZ1bmN0aW9uKCB0aW1lU2NhbGUgKSB7XG5cblx0XHR0aGlzLnRpbWVTY2FsZSA9IHRpbWVTY2FsZTtcblx0XHR0aGlzLl9lZmZlY3RpdmVUaW1lU2NhbGUgPSB0aGlzLnBhdXNlZCA/IDAgOnRpbWVTY2FsZTtcblxuXHRcdHJldHVybiB0aGlzLnN0b3BXYXJwaW5nKCk7XG5cblx0fSxcblxuXHQvLyByZXR1cm4gdGhlIHRpbWUgc2NhbGUgY29uc2lkZXJpbmcgd2FycGluZyBhbmQgLnBhdXNlZFxuXHRnZXRFZmZlY3RpdmVUaW1lU2NhbGU6IGZ1bmN0aW9uKCkge1xuXG5cdFx0cmV0dXJuIHRoaXMuX2VmZmVjdGl2ZVRpbWVTY2FsZTtcblxuXHR9LFxuXG5cdHNldER1cmF0aW9uOiBmdW5jdGlvbiggZHVyYXRpb24gKSB7XG5cblx0XHR0aGlzLnRpbWVTY2FsZSA9IHRoaXMuX2NsaXAuZHVyYXRpb24gLyBkdXJhdGlvbjtcblxuXHRcdHJldHVybiB0aGlzLnN0b3BXYXJwaW5nKCk7XG5cblx0fSxcblxuXHRzeW5jV2l0aDogZnVuY3Rpb24oIGFjdGlvbiApIHtcblxuXHRcdHRoaXMudGltZSA9IGFjdGlvbi50aW1lO1xuXHRcdHRoaXMudGltZVNjYWxlID0gYWN0aW9uLnRpbWVTY2FsZTtcblxuXHRcdHJldHVybiB0aGlzLnN0b3BXYXJwaW5nKCk7XG5cblx0fSxcblxuXHRoYWx0OiBmdW5jdGlvbiggZHVyYXRpb24gKSB7XG5cblx0XHRyZXR1cm4gdGhpcy53YXJwKCB0aGlzLl9lZmZlY3RpdmVUaW1lU2NhbGUsIDAsIGR1cmF0aW9uICk7XG5cblx0fSxcblxuXHR3YXJwOiBmdW5jdGlvbiggc3RhcnRUaW1lU2NhbGUsIGVuZFRpbWVTY2FsZSwgZHVyYXRpb24gKSB7XG5cblx0XHR2YXIgbWl4ZXIgPSB0aGlzLl9taXhlciwgbm93ID0gbWl4ZXIudGltZSxcblx0XHRcdGludGVycG9sYW50ID0gdGhpcy5fdGltZVNjYWxlSW50ZXJwb2xhbnQsXG5cblx0XHRcdHRpbWVTY2FsZSA9IHRoaXMudGltZVNjYWxlO1xuXG5cdFx0aWYgKCBpbnRlcnBvbGFudCA9PT0gbnVsbCApIHtcblxuXHRcdFx0aW50ZXJwb2xhbnQgPSBtaXhlci5fbGVuZENvbnRyb2xJbnRlcnBvbGFudCgpO1xuXHRcdFx0dGhpcy5fdGltZVNjYWxlSW50ZXJwb2xhbnQgPSBpbnRlcnBvbGFudDtcblxuXHRcdH1cblxuXHRcdHZhciB0aW1lcyA9IGludGVycG9sYW50LnBhcmFtZXRlclBvc2l0aW9ucyxcblx0XHRcdHZhbHVlcyA9IGludGVycG9sYW50LnNhbXBsZVZhbHVlcztcblxuXHRcdHRpbWVzWyAwIF0gPSBub3c7XG5cdFx0dGltZXNbIDEgXSA9IG5vdyArIGR1cmF0aW9uO1xuXG5cdFx0dmFsdWVzWyAwIF0gPSBzdGFydFRpbWVTY2FsZSAvIHRpbWVTY2FsZTtcblx0XHR2YWx1ZXNbIDEgXSA9IGVuZFRpbWVTY2FsZSAvIHRpbWVTY2FsZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c3RvcFdhcnBpbmc6IGZ1bmN0aW9uKCkge1xuXG5cdFx0dmFyIHRpbWVTY2FsZUludGVycG9sYW50ID0gdGhpcy5fdGltZVNjYWxlSW50ZXJwb2xhbnQ7XG5cblx0XHRpZiAoIHRpbWVTY2FsZUludGVycG9sYW50ICE9PSBudWxsICkge1xuXG5cdFx0XHR0aGlzLl90aW1lU2NhbGVJbnRlcnBvbGFudCA9IG51bGw7XG5cdFx0XHR0aGlzLl9taXhlci5fdGFrZUJhY2tDb250cm9sSW50ZXJwb2xhbnQoIHRpbWVTY2FsZUludGVycG9sYW50ICk7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdC8vIE9iamVjdCBBY2Nlc3NvcnNcblxuXHRnZXRNaXhlcjogZnVuY3Rpb24oKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5fbWl4ZXI7XG5cblx0fSxcblxuXHRnZXRDbGlwOiBmdW5jdGlvbigpIHtcblxuXHRcdHJldHVybiB0aGlzLl9jbGlwO1xuXG5cdH0sXG5cblx0Z2V0Um9vdDogZnVuY3Rpb24oKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5fbG9jYWxSb290IHx8IHRoaXMuX21peGVyLl9yb290O1xuXG5cdH0sXG5cblx0Ly8gSW50ZXJuYVxuXG5cdF91cGRhdGU6IGZ1bmN0aW9uKCB0aW1lLCBkZWx0YVRpbWUsIHRpbWVEaXJlY3Rpb24sIGFjY3VJbmRleCApIHtcblxuXHRcdC8vIGNhbGxlZCBieSB0aGUgbWl4ZXJcblxuXHRcdGlmICggISB0aGlzLmVuYWJsZWQgKSB7XG5cblx0XHRcdC8vIGNhbGwgLl91cGRhdGVXZWlnaHQoKSB0byB1cGRhdGUgLl9lZmZlY3RpdmVXZWlnaHRcblxuXHRcdFx0dGhpcy5fdXBkYXRlV2VpZ2h0KCB0aW1lICk7XG5cdFx0XHRyZXR1cm47XG5cblx0XHR9XG5cblx0XHR2YXIgc3RhcnRUaW1lID0gdGhpcy5fc3RhcnRUaW1lO1xuXG5cdFx0aWYgKCBzdGFydFRpbWUgIT09IG51bGwgKSB7XG5cblx0XHRcdC8vIGNoZWNrIGZvciBzY2hlZHVsZWQgc3RhcnQgb2YgYWN0aW9uXG5cblx0XHRcdHZhciB0aW1lUnVubmluZyA9ICggdGltZSAtIHN0YXJ0VGltZSApICogdGltZURpcmVjdGlvbjtcblx0XHRcdGlmICggdGltZVJ1bm5pbmcgPCAwIHx8IHRpbWVEaXJlY3Rpb24gPT09IDAgKSB7XG5cblx0XHRcdFx0cmV0dXJuOyAvLyB5ZXQgdG8gY29tZSAvIGRvbid0IGRlY2lkZSB3aGVuIGRlbHRhID0gMFxuXG5cdFx0XHR9XG5cblx0XHRcdC8vIHN0YXJ0XG5cblx0XHRcdHRoaXMuX3N0YXJ0VGltZSA9IG51bGw7IC8vIHVuc2NoZWR1bGVcblx0XHRcdGRlbHRhVGltZSA9IHRpbWVEaXJlY3Rpb24gKiB0aW1lUnVubmluZztcblxuXHRcdH1cblxuXHRcdC8vIGFwcGx5IHRpbWUgc2NhbGUgYW5kIGFkdmFuY2UgdGltZVxuXG5cdFx0ZGVsdGFUaW1lICo9IHRoaXMuX3VwZGF0ZVRpbWVTY2FsZSggdGltZSApO1xuXHRcdHZhciBjbGlwVGltZSA9IHRoaXMuX3VwZGF0ZVRpbWUoIGRlbHRhVGltZSApO1xuXG5cdFx0Ly8gbm90ZTogX3VwZGF0ZVRpbWUgbWF5IGRpc2FibGUgdGhlIGFjdGlvbiByZXN1bHRpbmcgaW5cblx0XHQvLyBhbiBlZmZlY3RpdmUgd2VpZ2h0IG9mIDBcblxuXHRcdHZhciB3ZWlnaHQgPSB0aGlzLl91cGRhdGVXZWlnaHQoIHRpbWUgKTtcblxuXHRcdGlmICggd2VpZ2h0ID4gMCApIHtcblxuXHRcdFx0dmFyIGludGVycG9sYW50cyA9IHRoaXMuX2ludGVycG9sYW50cztcblx0XHRcdHZhciBwcm9wZXJ0eU1peGVycyA9IHRoaXMuX3Byb3BlcnR5QmluZGluZ3M7XG5cblx0XHRcdGZvciAoIHZhciBqID0gMCwgbSA9IGludGVycG9sYW50cy5sZW5ndGg7IGogIT09IG07ICsrIGogKSB7XG5cblx0XHRcdFx0aW50ZXJwb2xhbnRzWyBqIF0uZXZhbHVhdGUoIGNsaXBUaW1lICk7XG5cdFx0XHRcdHByb3BlcnR5TWl4ZXJzWyBqIF0uYWNjdW11bGF0ZSggYWNjdUluZGV4LCB3ZWlnaHQgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0X3VwZGF0ZVdlaWdodDogZnVuY3Rpb24oIHRpbWUgKSB7XG5cblx0XHR2YXIgd2VpZ2h0ID0gMDtcblxuXHRcdGlmICggdGhpcy5lbmFibGVkICkge1xuXG5cdFx0XHR3ZWlnaHQgPSB0aGlzLndlaWdodDtcblx0XHRcdHZhciBpbnRlcnBvbGFudCA9IHRoaXMuX3dlaWdodEludGVycG9sYW50O1xuXG5cdFx0XHRpZiAoIGludGVycG9sYW50ICE9PSBudWxsICkge1xuXG5cdFx0XHRcdHZhciBpbnRlcnBvbGFudFZhbHVlID0gaW50ZXJwb2xhbnQuZXZhbHVhdGUoIHRpbWUgKVsgMCBdO1xuXG5cdFx0XHRcdHdlaWdodCAqPSBpbnRlcnBvbGFudFZhbHVlO1xuXG5cdFx0XHRcdGlmICggdGltZSA+IGludGVycG9sYW50LnBhcmFtZXRlclBvc2l0aW9uc1sgMSBdICkge1xuXG5cdFx0XHRcdFx0dGhpcy5zdG9wRmFkaW5nKCk7XG5cblx0XHRcdFx0XHRpZiAoIGludGVycG9sYW50VmFsdWUgPT09IDAgKSB7XG5cblx0XHRcdFx0XHRcdC8vIGZhZGVkIG91dCwgZGlzYWJsZVxuXHRcdFx0XHRcdFx0dGhpcy5lbmFibGVkID0gZmFsc2U7XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHR0aGlzLl9lZmZlY3RpdmVXZWlnaHQgPSB3ZWlnaHQ7XG5cdFx0cmV0dXJuIHdlaWdodDtcblxuXHR9LFxuXG5cdF91cGRhdGVUaW1lU2NhbGU6IGZ1bmN0aW9uKCB0aW1lICkge1xuXG5cdFx0dmFyIHRpbWVTY2FsZSA9IDA7XG5cblx0XHRpZiAoICEgdGhpcy5wYXVzZWQgKSB7XG5cblx0XHRcdHRpbWVTY2FsZSA9IHRoaXMudGltZVNjYWxlO1xuXG5cdFx0XHR2YXIgaW50ZXJwb2xhbnQgPSB0aGlzLl90aW1lU2NhbGVJbnRlcnBvbGFudDtcblxuXHRcdFx0aWYgKCBpbnRlcnBvbGFudCAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHR2YXIgaW50ZXJwb2xhbnRWYWx1ZSA9IGludGVycG9sYW50LmV2YWx1YXRlKCB0aW1lIClbIDAgXTtcblxuXHRcdFx0XHR0aW1lU2NhbGUgKj0gaW50ZXJwb2xhbnRWYWx1ZTtcblxuXHRcdFx0XHRpZiAoIHRpbWUgPiBpbnRlcnBvbGFudC5wYXJhbWV0ZXJQb3NpdGlvbnNbIDEgXSApIHtcblxuXHRcdFx0XHRcdHRoaXMuc3RvcFdhcnBpbmcoKTtcblxuXHRcdFx0XHRcdGlmICggdGltZVNjYWxlID09PSAwICkge1xuXG5cdFx0XHRcdFx0XHQvLyBtb3Rpb24gaGFzIGhhbHRlZCwgcGF1c2Vcblx0XHRcdFx0XHRcdHRoaXMucGF1c2VkID0gdHJ1ZTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIHdhcnAgZG9uZSAtIGFwcGx5IGZpbmFsIHRpbWUgc2NhbGVcblx0XHRcdFx0XHRcdHRoaXMudGltZVNjYWxlID0gdGltZVNjYWxlO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0dGhpcy5fZWZmZWN0aXZlVGltZVNjYWxlID0gdGltZVNjYWxlO1xuXHRcdHJldHVybiB0aW1lU2NhbGU7XG5cblx0fSxcblxuXHRfdXBkYXRlVGltZTogZnVuY3Rpb24oIGRlbHRhVGltZSApIHtcblxuXHRcdHZhciB0aW1lID0gdGhpcy50aW1lICsgZGVsdGFUaW1lO1xuXG5cdFx0aWYgKCBkZWx0YVRpbWUgPT09IDAgKSByZXR1cm4gdGltZTtcblxuXHRcdHZhciBkdXJhdGlvbiA9IHRoaXMuX2NsaXAuZHVyYXRpb24sXG5cblx0XHRcdGxvb3AgPSB0aGlzLmxvb3AsXG5cdFx0XHRsb29wQ291bnQgPSB0aGlzLl9sb29wQ291bnQ7XG5cblx0XHRpZiAoIGxvb3AgPT09IExvb3BPbmNlICkge1xuXG5cdFx0XHRpZiAoIGxvb3BDb3VudCA9PT0gLTEgKSB7XG5cdFx0XHRcdC8vIGp1c3Qgc3RhcnRlZFxuXG5cdFx0XHRcdHRoaXMuX2xvb3BDb3VudCA9IDA7XG5cdFx0XHRcdHRoaXMuX3NldEVuZGluZ3MoIHRydWUsIHRydWUsIGZhbHNlICk7XG5cblx0XHRcdH1cblxuXHRcdFx0aGFuZGxlX3N0b3A6IHtcblxuXHRcdFx0XHRpZiAoIHRpbWUgPj0gZHVyYXRpb24gKSB7XG5cblx0XHRcdFx0XHR0aW1lID0gZHVyYXRpb247XG5cblx0XHRcdFx0fSBlbHNlIGlmICggdGltZSA8IDAgKSB7XG5cblx0XHRcdFx0XHR0aW1lID0gMDtcblxuXHRcdFx0XHR9IGVsc2UgYnJlYWsgaGFuZGxlX3N0b3A7XG5cblx0XHRcdFx0aWYgKCB0aGlzLmNsYW1wV2hlbkZpbmlzaGVkICkgdGhpcy5wYXVzZWQgPSB0cnVlO1xuXHRcdFx0XHRlbHNlIHRoaXMuZW5hYmxlZCA9IGZhbHNlO1xuXG5cdFx0XHRcdHRoaXMuX21peGVyLmRpc3BhdGNoRXZlbnQoIHtcblx0XHRcdFx0XHR0eXBlOiAnZmluaXNoZWQnLCBhY3Rpb246IHRoaXMsXG5cdFx0XHRcdFx0ZGlyZWN0aW9uOiBkZWx0YVRpbWUgPCAwID8gLTEgOiAxXG5cdFx0XHRcdH0gKTtcblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHsgLy8gcmVwZXRpdGl2ZSBSZXBlYXQgb3IgUGluZ1BvbmdcblxuXHRcdFx0dmFyIHBpbmdQb25nID0gKCBsb29wID09PSBMb29wUGluZ1BvbmcgKTtcblxuXHRcdFx0aWYgKCBsb29wQ291bnQgPT09IC0xICkge1xuXHRcdFx0XHQvLyBqdXN0IHN0YXJ0ZWRcblxuXHRcdFx0XHRpZiAoIGRlbHRhVGltZSA+PSAwICkge1xuXG5cdFx0XHRcdFx0bG9vcENvdW50ID0gMDtcblxuXHRcdFx0XHRcdHRoaXMuX3NldEVuZGluZ3MoXG5cdFx0XHRcdFx0XHRcdHRydWUsIHRoaXMucmVwZXRpdGlvbnMgPT09IDAsIHBpbmdQb25nICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdC8vIHdoZW4gbG9vcGluZyBpbiByZXZlcnNlIGRpcmVjdGlvbiwgdGhlIGluaXRpYWxcblx0XHRcdFx0XHQvLyB0cmFuc2l0aW9uIHRocm91Z2ggemVybyBjb3VudHMgYXMgYSByZXBldGl0aW9uLFxuXHRcdFx0XHRcdC8vIHNvIGxlYXZlIGxvb3BDb3VudCBhdCAtMVxuXG5cdFx0XHRcdFx0dGhpcy5fc2V0RW5kaW5ncyhcblx0XHRcdFx0XHRcdFx0dGhpcy5yZXBldGl0aW9ucyA9PT0gMCwgdHJ1ZSwgcGluZ1BvbmcgKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCB0aW1lID49IGR1cmF0aW9uIHx8IHRpbWUgPCAwICkge1xuXHRcdFx0XHQvLyB3cmFwIGFyb3VuZFxuXG5cdFx0XHRcdHZhciBsb29wRGVsdGEgPSBNYXRoLmZsb29yKCB0aW1lIC8gZHVyYXRpb24gKTsgLy8gc2lnbmVkXG5cdFx0XHRcdHRpbWUgLT0gZHVyYXRpb24gKiBsb29wRGVsdGE7XG5cblx0XHRcdFx0bG9vcENvdW50ICs9IE1hdGguYWJzKCBsb29wRGVsdGEgKTtcblxuXHRcdFx0XHR2YXIgcGVuZGluZyA9IHRoaXMucmVwZXRpdGlvbnMgLSBsb29wQ291bnQ7XG5cblx0XHRcdFx0aWYgKCBwZW5kaW5nIDwgMCApIHtcblx0XHRcdFx0XHQvLyBoYXZlIHRvIHN0b3AgKHN3aXRjaCBzdGF0ZSwgY2xhbXAgdGltZSwgZmlyZSBldmVudClcblxuXHRcdFx0XHRcdGlmICggdGhpcy5jbGFtcFdoZW5GaW5pc2hlZCApIHRoaXMucGF1c2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRlbHNlIHRoaXMuZW5hYmxlZCA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0dGltZSA9IGRlbHRhVGltZSA+IDAgPyBkdXJhdGlvbiA6IDA7XG5cblx0XHRcdFx0XHR0aGlzLl9taXhlci5kaXNwYXRjaEV2ZW50KCB7XG5cdFx0XHRcdFx0XHR0eXBlOiAnZmluaXNoZWQnLCBhY3Rpb246IHRoaXMsXG5cdFx0XHRcdFx0XHRkaXJlY3Rpb246IGRlbHRhVGltZSA+IDAgPyAxIDogLTFcblx0XHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBrZWVwIHJ1bm5pbmdcblxuXHRcdFx0XHRcdGlmICggcGVuZGluZyA9PT0gMCApIHtcblx0XHRcdFx0XHRcdC8vIGVudGVyaW5nIHRoZSBsYXN0IHJvdW5kXG5cblx0XHRcdFx0XHRcdHZhciBhdFN0YXJ0ID0gZGVsdGFUaW1lIDwgMDtcblx0XHRcdFx0XHRcdHRoaXMuX3NldEVuZGluZ3MoIGF0U3RhcnQsICEgYXRTdGFydCwgcGluZ1BvbmcgKTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdHRoaXMuX3NldEVuZGluZ3MoIGZhbHNlLCBmYWxzZSwgcGluZ1BvbmcgKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHRoaXMuX2xvb3BDb3VudCA9IGxvb3BDb3VudDtcblxuXHRcdFx0XHRcdHRoaXMuX21peGVyLmRpc3BhdGNoRXZlbnQoIHtcblx0XHRcdFx0XHRcdHR5cGU6ICdsb29wJywgYWN0aW9uOiB0aGlzLCBsb29wRGVsdGE6IGxvb3BEZWx0YVxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBwaW5nUG9uZyAmJiAoIGxvb3BDb3VudCAmIDEgKSA9PT0gMSApIHtcblx0XHRcdFx0Ly8gaW52ZXJ0IHRpbWUgZm9yIHRoZSBcInBvbmcgcm91bmRcIlxuXG5cdFx0XHRcdHRoaXMudGltZSA9IHRpbWU7XG5cdFx0XHRcdHJldHVybiBkdXJhdGlvbiAtIHRpbWU7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHRoaXMudGltZSA9IHRpbWU7XG5cdFx0cmV0dXJuIHRpbWU7XG5cblx0fSxcblxuXHRfc2V0RW5kaW5nczogZnVuY3Rpb24oIGF0U3RhcnQsIGF0RW5kLCBwaW5nUG9uZyApIHtcblxuXHRcdHZhciBzZXR0aW5ncyA9IHRoaXMuX2ludGVycG9sYW50U2V0dGluZ3M7XG5cblx0XHRpZiAoIHBpbmdQb25nICkge1xuXG5cdFx0XHRzZXR0aW5ncy5lbmRpbmdTdGFydCBcdD0gWmVyb1Nsb3BlRW5kaW5nO1xuXHRcdFx0c2V0dGluZ3MuZW5kaW5nRW5kXHRcdD0gWmVyb1Nsb3BlRW5kaW5nO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gYXNzdW1pbmcgZm9yIExvb3BPbmNlIGF0U3RhcnQgPT0gYXRFbmQgPT0gdHJ1ZVxuXG5cdFx0XHRpZiAoIGF0U3RhcnQgKSB7XG5cblx0XHRcdFx0c2V0dGluZ3MuZW5kaW5nU3RhcnQgPSB0aGlzLnplcm9TbG9wZUF0U3RhcnQgP1xuXHRcdFx0XHRcdFx0WmVyb1Nsb3BlRW5kaW5nIDogWmVyb0N1cnZhdHVyZUVuZGluZztcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRzZXR0aW5ncy5lbmRpbmdTdGFydCA9IFdyYXBBcm91bmRFbmRpbmc7XG5cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBhdEVuZCApIHtcblxuXHRcdFx0XHRzZXR0aW5ncy5lbmRpbmdFbmQgPSB0aGlzLnplcm9TbG9wZUF0RW5kID9cblx0XHRcdFx0XHRcdFplcm9TbG9wZUVuZGluZyA6IFplcm9DdXJ2YXR1cmVFbmRpbmc7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0c2V0dGluZ3MuZW5kaW5nRW5kIFx0ID0gV3JhcEFyb3VuZEVuZGluZztcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0X3NjaGVkdWxlRmFkaW5nOiBmdW5jdGlvbiggZHVyYXRpb24sIHdlaWdodE5vdywgd2VpZ2h0VGhlbiApIHtcblxuXHRcdHZhciBtaXhlciA9IHRoaXMuX21peGVyLCBub3cgPSBtaXhlci50aW1lLFxuXHRcdFx0aW50ZXJwb2xhbnQgPSB0aGlzLl93ZWlnaHRJbnRlcnBvbGFudDtcblxuXHRcdGlmICggaW50ZXJwb2xhbnQgPT09IG51bGwgKSB7XG5cblx0XHRcdGludGVycG9sYW50ID0gbWl4ZXIuX2xlbmRDb250cm9sSW50ZXJwb2xhbnQoKTtcblx0XHRcdHRoaXMuX3dlaWdodEludGVycG9sYW50ID0gaW50ZXJwb2xhbnQ7XG5cblx0XHR9XG5cblx0XHR2YXIgdGltZXMgPSBpbnRlcnBvbGFudC5wYXJhbWV0ZXJQb3NpdGlvbnMsXG5cdFx0XHR2YWx1ZXMgPSBpbnRlcnBvbGFudC5zYW1wbGVWYWx1ZXM7XG5cblx0XHR0aW1lc1sgMCBdID0gbm93OyBcdFx0XHRcdHZhbHVlc1sgMCBdID0gd2VpZ2h0Tm93O1xuXHRcdHRpbWVzWyAxIF0gPSBub3cgKyBkdXJhdGlvbjtcdHZhbHVlc1sgMSBdID0gd2VpZ2h0VGhlbjtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqXG4gKiBQbGF5ZXIgZm9yIEFuaW1hdGlvbkNsaXBzLlxuICpcbiAqXG4gKiBAYXV0aG9yIEJlbiBIb3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBEYXZpZCBTYXJubyAvIGh0dHA6Ly9saWdodGhhdXMudXMvXG4gKiBAYXV0aG9yIHRzY2h3XG4gKi9cblxuZnVuY3Rpb24gQW5pbWF0aW9uTWl4ZXIoIHJvb3QgKSB7XG5cblx0dGhpcy5fcm9vdCA9IHJvb3Q7XG5cdHRoaXMuX2luaXRNZW1vcnlNYW5hZ2VyKCk7XG5cdHRoaXMuX2FjY3VJbmRleCA9IDA7XG5cblx0dGhpcy50aW1lID0gMDtcblxuXHR0aGlzLnRpbWVTY2FsZSA9IDEuMDtcblxufVxuXG5PYmplY3QuYXNzaWduKCBBbmltYXRpb25NaXhlci5wcm90b3R5cGUsIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUsIHtcblxuXHRfYmluZEFjdGlvbjogZnVuY3Rpb24gKCBhY3Rpb24sIHByb3RvdHlwZUFjdGlvbiApIHtcblxuXHRcdHZhciByb290ID0gYWN0aW9uLl9sb2NhbFJvb3QgfHwgdGhpcy5fcm9vdCxcblx0XHRcdHRyYWNrcyA9IGFjdGlvbi5fY2xpcC50cmFja3MsXG5cdFx0XHRuVHJhY2tzID0gdHJhY2tzLmxlbmd0aCxcblx0XHRcdGJpbmRpbmdzID0gYWN0aW9uLl9wcm9wZXJ0eUJpbmRpbmdzLFxuXHRcdFx0aW50ZXJwb2xhbnRzID0gYWN0aW9uLl9pbnRlcnBvbGFudHMsXG5cdFx0XHRyb290VXVpZCA9IHJvb3QudXVpZCxcblx0XHRcdGJpbmRpbmdzQnlSb290ID0gdGhpcy5fYmluZGluZ3NCeVJvb3RBbmROYW1lLFxuXHRcdFx0YmluZGluZ3NCeU5hbWUgPSBiaW5kaW5nc0J5Um9vdFsgcm9vdFV1aWQgXTtcblxuXHRcdGlmICggYmluZGluZ3NCeU5hbWUgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0YmluZGluZ3NCeU5hbWUgPSB7fTtcblx0XHRcdGJpbmRpbmdzQnlSb290WyByb290VXVpZCBdID0gYmluZGluZ3NCeU5hbWU7XG5cblx0XHR9XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgIT09IG5UcmFja3M7ICsrIGkgKSB7XG5cblx0XHRcdHZhciB0cmFjayA9IHRyYWNrc1sgaSBdLFxuXHRcdFx0XHR0cmFja05hbWUgPSB0cmFjay5uYW1lLFxuXHRcdFx0XHRiaW5kaW5nID0gYmluZGluZ3NCeU5hbWVbIHRyYWNrTmFtZSBdO1xuXG5cdFx0XHRpZiAoIGJpbmRpbmcgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRiaW5kaW5nc1sgaSBdID0gYmluZGluZztcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRiaW5kaW5nID0gYmluZGluZ3NbIGkgXTtcblxuXHRcdFx0XHRpZiAoIGJpbmRpbmcgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRcdC8vIGV4aXN0aW5nIGJpbmRpbmcsIG1ha2Ugc3VyZSB0aGUgY2FjaGUga25vd3NcblxuXHRcdFx0XHRcdGlmICggYmluZGluZy5fY2FjaGVJbmRleCA9PT0gbnVsbCApIHtcblxuXHRcdFx0XHRcdFx0KysgYmluZGluZy5yZWZlcmVuY2VDb3VudDtcblx0XHRcdFx0XHRcdHRoaXMuX2FkZEluYWN0aXZlQmluZGluZyggYmluZGluZywgcm9vdFV1aWQsIHRyYWNrTmFtZSApO1xuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y29udGludWU7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBwYXRoID0gcHJvdG90eXBlQWN0aW9uICYmIHByb3RvdHlwZUFjdGlvbi5cblx0XHRcdFx0XHRcdF9wcm9wZXJ0eUJpbmRpbmdzWyBpIF0uYmluZGluZy5wYXJzZWRQYXRoO1xuXG5cdFx0XHRcdGJpbmRpbmcgPSBuZXcgUHJvcGVydHlNaXhlcihcblx0XHRcdFx0XHRQcm9wZXJ0eUJpbmRpbmcuY3JlYXRlKCByb290LCB0cmFja05hbWUsIHBhdGggKSxcblx0XHRcdFx0XHR0cmFjay5WYWx1ZVR5cGVOYW1lLCB0cmFjay5nZXRWYWx1ZVNpemUoKSApO1xuXG5cdFx0XHRcdCsrIGJpbmRpbmcucmVmZXJlbmNlQ291bnQ7XG5cdFx0XHRcdHRoaXMuX2FkZEluYWN0aXZlQmluZGluZyggYmluZGluZywgcm9vdFV1aWQsIHRyYWNrTmFtZSApO1xuXG5cdFx0XHRcdGJpbmRpbmdzWyBpIF0gPSBiaW5kaW5nO1xuXG5cdFx0XHR9XG5cblx0XHRcdGludGVycG9sYW50c1sgaSBdLnJlc3VsdEJ1ZmZlciA9IGJpbmRpbmcuYnVmZmVyO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0X2FjdGl2YXRlQWN0aW9uOiBmdW5jdGlvbiAoIGFjdGlvbiApIHtcblxuXHRcdGlmICggISB0aGlzLl9pc0FjdGl2ZUFjdGlvbiggYWN0aW9uICkgKSB7XG5cblx0XHRcdGlmICggYWN0aW9uLl9jYWNoZUluZGV4ID09PSBudWxsICkge1xuXG5cdFx0XHRcdC8vIHRoaXMgYWN0aW9uIGhhcyBiZWVuIGZvcmdvdHRlbiBieSB0aGUgY2FjaGUsIGJ1dCB0aGUgdXNlclxuXHRcdFx0XHQvLyBhcHBlYXJzIHRvIGJlIHN0aWxsIHVzaW5nIGl0IC0+IHJlYmluZFxuXG5cdFx0XHRcdHZhciByb290VXVpZCA9ICggYWN0aW9uLl9sb2NhbFJvb3QgfHwgdGhpcy5fcm9vdCApLnV1aWQsXG5cdFx0XHRcdFx0Y2xpcFV1aWQgPSBhY3Rpb24uX2NsaXAudXVpZCxcblx0XHRcdFx0XHRhY3Rpb25zRm9yQ2xpcCA9IHRoaXMuX2FjdGlvbnNCeUNsaXBbIGNsaXBVdWlkIF07XG5cblx0XHRcdFx0dGhpcy5fYmluZEFjdGlvbiggYWN0aW9uLFxuXHRcdFx0XHRcdGFjdGlvbnNGb3JDbGlwICYmIGFjdGlvbnNGb3JDbGlwLmtub3duQWN0aW9uc1sgMCBdICk7XG5cblx0XHRcdFx0dGhpcy5fYWRkSW5hY3RpdmVBY3Rpb24oIGFjdGlvbiwgY2xpcFV1aWQsIHJvb3RVdWlkICk7XG5cblx0XHRcdH1cblxuXHRcdFx0dmFyIGJpbmRpbmdzID0gYWN0aW9uLl9wcm9wZXJ0eUJpbmRpbmdzO1xuXG5cdFx0XHQvLyBpbmNyZW1lbnQgcmVmZXJlbmNlIGNvdW50cyAvIHNvcnQgb3V0IHN0YXRlXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIG4gPSBiaW5kaW5ncy5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdFx0dmFyIGJpbmRpbmcgPSBiaW5kaW5nc1sgaSBdO1xuXG5cdFx0XHRcdGlmICggYmluZGluZy51c2VDb3VudCArKyA9PT0gMCApIHtcblxuXHRcdFx0XHRcdHRoaXMuX2xlbmRCaW5kaW5nKCBiaW5kaW5nICk7XG5cdFx0XHRcdFx0YmluZGluZy5zYXZlT3JpZ2luYWxTdGF0ZSgpO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9sZW5kQWN0aW9uKCBhY3Rpb24gKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdF9kZWFjdGl2YXRlQWN0aW9uOiBmdW5jdGlvbiAoIGFjdGlvbiApIHtcblxuXHRcdGlmICggdGhpcy5faXNBY3RpdmVBY3Rpb24oIGFjdGlvbiApICkge1xuXG5cdFx0XHR2YXIgYmluZGluZ3MgPSBhY3Rpb24uX3Byb3BlcnR5QmluZGluZ3M7XG5cblx0XHRcdC8vIGRlY3JlbWVudCByZWZlcmVuY2UgY291bnRzIC8gc29ydCBvdXQgc3RhdGVcblx0XHRcdGZvciAoIHZhciBpID0gMCwgbiA9IGJpbmRpbmdzLmxlbmd0aDsgaSAhPT0gbjsgKysgaSApIHtcblxuXHRcdFx0XHR2YXIgYmluZGluZyA9IGJpbmRpbmdzWyBpIF07XG5cblx0XHRcdFx0aWYgKCAtLSBiaW5kaW5nLnVzZUNvdW50ID09PSAwICkge1xuXG5cdFx0XHRcdFx0YmluZGluZy5yZXN0b3JlT3JpZ2luYWxTdGF0ZSgpO1xuXHRcdFx0XHRcdHRoaXMuX3Rha2VCYWNrQmluZGluZyggYmluZGluZyApO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl90YWtlQmFja0FjdGlvbiggYWN0aW9uICk7XG5cblx0XHR9XG5cblx0fSxcblxuXHQvLyBNZW1vcnkgbWFuYWdlclxuXG5cdF9pbml0TWVtb3J5TWFuYWdlcjogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5fYWN0aW9ucyA9IFtdOyAvLyAnbkFjdGl2ZUFjdGlvbnMnIGZvbGxvd2VkIGJ5IGluYWN0aXZlIG9uZXNcblx0XHR0aGlzLl9uQWN0aXZlQWN0aW9ucyA9IDA7XG5cblx0XHR0aGlzLl9hY3Rpb25zQnlDbGlwID0ge307XG5cdFx0Ly8gaW5zaWRlOlxuXHRcdC8vIHtcblx0XHQvLyBcdFx0a25vd25BY3Rpb25zOiBBcnJheTwgQW5pbWF0aW9uQWN0aW9uID5cdC0gdXNlZCBhcyBwcm90b3R5cGVzXG5cdFx0Ly8gXHRcdGFjdGlvbkJ5Um9vdDogQW5pbWF0aW9uQWN0aW9uXHRcdFx0LSBsb29rdXBcblx0XHQvLyB9XG5cblxuXHRcdHRoaXMuX2JpbmRpbmdzID0gW107IC8vICduQWN0aXZlQmluZGluZ3MnIGZvbGxvd2VkIGJ5IGluYWN0aXZlIG9uZXNcblx0XHR0aGlzLl9uQWN0aXZlQmluZGluZ3MgPSAwO1xuXG5cdFx0dGhpcy5fYmluZGluZ3NCeVJvb3RBbmROYW1lID0ge307IC8vIGluc2lkZTogTWFwPCBuYW1lLCBQcm9wZXJ0eU1peGVyID5cblxuXG5cdFx0dGhpcy5fY29udHJvbEludGVycG9sYW50cyA9IFtdOyAvLyBzYW1lIGdhbWUgYXMgYWJvdmVcblx0XHR0aGlzLl9uQWN0aXZlQ29udHJvbEludGVycG9sYW50cyA9IDA7XG5cblx0XHR2YXIgc2NvcGUgPSB0aGlzO1xuXG5cdFx0dGhpcy5zdGF0cyA9IHtcblxuXHRcdFx0YWN0aW9uczoge1xuXHRcdFx0XHRnZXQgdG90YWwoKSB7IHJldHVybiBzY29wZS5fYWN0aW9ucy5sZW5ndGg7IH0sXG5cdFx0XHRcdGdldCBpblVzZSgpIHsgcmV0dXJuIHNjb3BlLl9uQWN0aXZlQWN0aW9uczsgfVxuXHRcdFx0fSxcblx0XHRcdGJpbmRpbmdzOiB7XG5cdFx0XHRcdGdldCB0b3RhbCgpIHsgcmV0dXJuIHNjb3BlLl9iaW5kaW5ncy5sZW5ndGg7IH0sXG5cdFx0XHRcdGdldCBpblVzZSgpIHsgcmV0dXJuIHNjb3BlLl9uQWN0aXZlQmluZGluZ3M7IH1cblx0XHRcdH0sXG5cdFx0XHRjb250cm9sSW50ZXJwb2xhbnRzOiB7XG5cdFx0XHRcdGdldCB0b3RhbCgpIHsgcmV0dXJuIHNjb3BlLl9jb250cm9sSW50ZXJwb2xhbnRzLmxlbmd0aDsgfSxcblx0XHRcdFx0Z2V0IGluVXNlKCkgeyByZXR1cm4gc2NvcGUuX25BY3RpdmVDb250cm9sSW50ZXJwb2xhbnRzOyB9XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdH0sXG5cblx0Ly8gTWVtb3J5IG1hbmFnZW1lbnQgZm9yIEFuaW1hdGlvbkFjdGlvbiBvYmplY3RzXG5cblx0X2lzQWN0aXZlQWN0aW9uOiBmdW5jdGlvbiAoIGFjdGlvbiApIHtcblxuXHRcdHZhciBpbmRleCA9IGFjdGlvbi5fY2FjaGVJbmRleDtcblx0XHRyZXR1cm4gaW5kZXggIT09IG51bGwgJiYgaW5kZXggPCB0aGlzLl9uQWN0aXZlQWN0aW9ucztcblxuXHR9LFxuXG5cdF9hZGRJbmFjdGl2ZUFjdGlvbjogZnVuY3Rpb24gKCBhY3Rpb24sIGNsaXBVdWlkLCByb290VXVpZCApIHtcblxuXHRcdHZhciBhY3Rpb25zID0gdGhpcy5fYWN0aW9ucyxcblx0XHRcdGFjdGlvbnNCeUNsaXAgPSB0aGlzLl9hY3Rpb25zQnlDbGlwLFxuXHRcdFx0YWN0aW9uc0ZvckNsaXAgPSBhY3Rpb25zQnlDbGlwWyBjbGlwVXVpZCBdO1xuXG5cdFx0aWYgKCBhY3Rpb25zRm9yQ2xpcCA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRhY3Rpb25zRm9yQ2xpcCA9IHtcblxuXHRcdFx0XHRrbm93bkFjdGlvbnM6IFsgYWN0aW9uIF0sXG5cdFx0XHRcdGFjdGlvbkJ5Um9vdDoge31cblxuXHRcdFx0fTtcblxuXHRcdFx0YWN0aW9uLl9ieUNsaXBDYWNoZUluZGV4ID0gMDtcblxuXHRcdFx0YWN0aW9uc0J5Q2xpcFsgY2xpcFV1aWQgXSA9IGFjdGlvbnNGb3JDbGlwO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dmFyIGtub3duQWN0aW9ucyA9IGFjdGlvbnNGb3JDbGlwLmtub3duQWN0aW9ucztcblxuXHRcdFx0YWN0aW9uLl9ieUNsaXBDYWNoZUluZGV4ID0ga25vd25BY3Rpb25zLmxlbmd0aDtcblx0XHRcdGtub3duQWN0aW9ucy5wdXNoKCBhY3Rpb24gKTtcblxuXHRcdH1cblxuXHRcdGFjdGlvbi5fY2FjaGVJbmRleCA9IGFjdGlvbnMubGVuZ3RoO1xuXHRcdGFjdGlvbnMucHVzaCggYWN0aW9uICk7XG5cblx0XHRhY3Rpb25zRm9yQ2xpcC5hY3Rpb25CeVJvb3RbIHJvb3RVdWlkIF0gPSBhY3Rpb247XG5cblx0fSxcblxuXHRfcmVtb3ZlSW5hY3RpdmVBY3Rpb246IGZ1bmN0aW9uICggYWN0aW9uICkge1xuXG5cdFx0dmFyIGFjdGlvbnMgPSB0aGlzLl9hY3Rpb25zLFxuXHRcdFx0bGFzdEluYWN0aXZlQWN0aW9uID0gYWN0aW9uc1sgYWN0aW9ucy5sZW5ndGggLSAxIF0sXG5cdFx0XHRjYWNoZUluZGV4ID0gYWN0aW9uLl9jYWNoZUluZGV4O1xuXG5cdFx0bGFzdEluYWN0aXZlQWN0aW9uLl9jYWNoZUluZGV4ID0gY2FjaGVJbmRleDtcblx0XHRhY3Rpb25zWyBjYWNoZUluZGV4IF0gPSBsYXN0SW5hY3RpdmVBY3Rpb247XG5cdFx0YWN0aW9ucy5wb3AoKTtcblxuXHRcdGFjdGlvbi5fY2FjaGVJbmRleCA9IG51bGw7XG5cblxuXHRcdHZhciBjbGlwVXVpZCA9IGFjdGlvbi5fY2xpcC51dWlkLFxuXHRcdFx0YWN0aW9uc0J5Q2xpcCA9IHRoaXMuX2FjdGlvbnNCeUNsaXAsXG5cdFx0XHRhY3Rpb25zRm9yQ2xpcCA9IGFjdGlvbnNCeUNsaXBbIGNsaXBVdWlkIF0sXG5cdFx0XHRrbm93bkFjdGlvbnNGb3JDbGlwID0gYWN0aW9uc0ZvckNsaXAua25vd25BY3Rpb25zLFxuXG5cdFx0XHRsYXN0S25vd25BY3Rpb24gPVxuXHRcdFx0XHRrbm93bkFjdGlvbnNGb3JDbGlwWyBrbm93bkFjdGlvbnNGb3JDbGlwLmxlbmd0aCAtIDEgXSxcblxuXHRcdFx0YnlDbGlwQ2FjaGVJbmRleCA9IGFjdGlvbi5fYnlDbGlwQ2FjaGVJbmRleDtcblxuXHRcdGxhc3RLbm93bkFjdGlvbi5fYnlDbGlwQ2FjaGVJbmRleCA9IGJ5Q2xpcENhY2hlSW5kZXg7XG5cdFx0a25vd25BY3Rpb25zRm9yQ2xpcFsgYnlDbGlwQ2FjaGVJbmRleCBdID0gbGFzdEtub3duQWN0aW9uO1xuXHRcdGtub3duQWN0aW9uc0ZvckNsaXAucG9wKCk7XG5cblx0XHRhY3Rpb24uX2J5Q2xpcENhY2hlSW5kZXggPSBudWxsO1xuXG5cblx0XHR2YXIgYWN0aW9uQnlSb290ID0gYWN0aW9uc0ZvckNsaXAuYWN0aW9uQnlSb290LFxuXHRcdFx0cm9vdFV1aWQgPSAoIGFjdGlvbi5fbG9jYWxSb290IHx8IHRoaXMuX3Jvb3QgKS51dWlkO1xuXG5cdFx0ZGVsZXRlIGFjdGlvbkJ5Um9vdFsgcm9vdFV1aWQgXTtcblxuXHRcdGlmICgga25vd25BY3Rpb25zRm9yQ2xpcC5sZW5ndGggPT09IDAgKSB7XG5cblx0XHRcdGRlbGV0ZSBhY3Rpb25zQnlDbGlwWyBjbGlwVXVpZCBdO1xuXG5cdFx0fVxuXG5cdFx0dGhpcy5fcmVtb3ZlSW5hY3RpdmVCaW5kaW5nc0ZvckFjdGlvbiggYWN0aW9uICk7XG5cblx0fSxcblxuXHRfcmVtb3ZlSW5hY3RpdmVCaW5kaW5nc0ZvckFjdGlvbjogZnVuY3Rpb24gKCBhY3Rpb24gKSB7XG5cblx0XHR2YXIgYmluZGluZ3MgPSBhY3Rpb24uX3Byb3BlcnR5QmluZGluZ3M7XG5cdFx0Zm9yICggdmFyIGkgPSAwLCBuID0gYmluZGluZ3MubGVuZ3RoOyBpICE9PSBuOyArKyBpICkge1xuXG5cdFx0XHR2YXIgYmluZGluZyA9IGJpbmRpbmdzWyBpIF07XG5cblx0XHRcdGlmICggLS0gYmluZGluZy5yZWZlcmVuY2VDb3VudCA9PT0gMCApIHtcblxuXHRcdFx0XHR0aGlzLl9yZW1vdmVJbmFjdGl2ZUJpbmRpbmcoIGJpbmRpbmcgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0X2xlbmRBY3Rpb246IGZ1bmN0aW9uICggYWN0aW9uICkge1xuXG5cdFx0Ly8gWyBhY3RpdmUgYWN0aW9ucyB8ICBpbmFjdGl2ZSBhY3Rpb25zICBdXG5cdFx0Ly8gWyAgYWN0aXZlIGFjdGlvbnMgPnwgaW5hY3RpdmUgYWN0aW9ucyBdXG5cdFx0Ly8gICAgICAgICAgICAgICAgIHMgICAgICAgIGFcblx0XHQvLyAgICAgICAgICAgICAgICAgIDwtc3dhcC0+XG5cdFx0Ly8gICAgICAgICAgICAgICAgIGEgICAgICAgIHNcblxuXHRcdHZhciBhY3Rpb25zID0gdGhpcy5fYWN0aW9ucyxcblx0XHRcdHByZXZJbmRleCA9IGFjdGlvbi5fY2FjaGVJbmRleCxcblxuXHRcdFx0bGFzdEFjdGl2ZUluZGV4ID0gdGhpcy5fbkFjdGl2ZUFjdGlvbnMgKyssXG5cblx0XHRcdGZpcnN0SW5hY3RpdmVBY3Rpb24gPSBhY3Rpb25zWyBsYXN0QWN0aXZlSW5kZXggXTtcblxuXHRcdGFjdGlvbi5fY2FjaGVJbmRleCA9IGxhc3RBY3RpdmVJbmRleDtcblx0XHRhY3Rpb25zWyBsYXN0QWN0aXZlSW5kZXggXSA9IGFjdGlvbjtcblxuXHRcdGZpcnN0SW5hY3RpdmVBY3Rpb24uX2NhY2hlSW5kZXggPSBwcmV2SW5kZXg7XG5cdFx0YWN0aW9uc1sgcHJldkluZGV4IF0gPSBmaXJzdEluYWN0aXZlQWN0aW9uO1xuXG5cdH0sXG5cblx0X3Rha2VCYWNrQWN0aW9uOiBmdW5jdGlvbiAoIGFjdGlvbiApIHtcblxuXHRcdC8vIFsgIGFjdGl2ZSBhY3Rpb25zICB8IGluYWN0aXZlIGFjdGlvbnMgXVxuXHRcdC8vIFsgYWN0aXZlIGFjdGlvbnMgfDwgaW5hY3RpdmUgYWN0aW9ucyAgXVxuXHRcdC8vICAgICAgICBhICAgICAgICBzXG5cdFx0Ly8gICAgICAgICA8LXN3YXAtPlxuXHRcdC8vICAgICAgICBzICAgICAgICBhXG5cblx0XHR2YXIgYWN0aW9ucyA9IHRoaXMuX2FjdGlvbnMsXG5cdFx0XHRwcmV2SW5kZXggPSBhY3Rpb24uX2NhY2hlSW5kZXgsXG5cblx0XHRcdGZpcnN0SW5hY3RpdmVJbmRleCA9IC0tIHRoaXMuX25BY3RpdmVBY3Rpb25zLFxuXG5cdFx0XHRsYXN0QWN0aXZlQWN0aW9uID0gYWN0aW9uc1sgZmlyc3RJbmFjdGl2ZUluZGV4IF07XG5cblx0XHRhY3Rpb24uX2NhY2hlSW5kZXggPSBmaXJzdEluYWN0aXZlSW5kZXg7XG5cdFx0YWN0aW9uc1sgZmlyc3RJbmFjdGl2ZUluZGV4IF0gPSBhY3Rpb247XG5cblx0XHRsYXN0QWN0aXZlQWN0aW9uLl9jYWNoZUluZGV4ID0gcHJldkluZGV4O1xuXHRcdGFjdGlvbnNbIHByZXZJbmRleCBdID0gbGFzdEFjdGl2ZUFjdGlvbjtcblxuXHR9LFxuXG5cdC8vIE1lbW9yeSBtYW5hZ2VtZW50IGZvciBQcm9wZXJ0eU1peGVyIG9iamVjdHNcblxuXHRfYWRkSW5hY3RpdmVCaW5kaW5nOiBmdW5jdGlvbiAoIGJpbmRpbmcsIHJvb3RVdWlkLCB0cmFja05hbWUgKSB7XG5cblx0XHR2YXIgYmluZGluZ3NCeVJvb3QgPSB0aGlzLl9iaW5kaW5nc0J5Um9vdEFuZE5hbWUsXG5cdFx0XHRiaW5kaW5nQnlOYW1lID0gYmluZGluZ3NCeVJvb3RbIHJvb3RVdWlkIF0sXG5cblx0XHRcdGJpbmRpbmdzID0gdGhpcy5fYmluZGluZ3M7XG5cblx0XHRpZiAoIGJpbmRpbmdCeU5hbWUgPT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0YmluZGluZ0J5TmFtZSA9IHt9O1xuXHRcdFx0YmluZGluZ3NCeVJvb3RbIHJvb3RVdWlkIF0gPSBiaW5kaW5nQnlOYW1lO1xuXG5cdFx0fVxuXG5cdFx0YmluZGluZ0J5TmFtZVsgdHJhY2tOYW1lIF0gPSBiaW5kaW5nO1xuXG5cdFx0YmluZGluZy5fY2FjaGVJbmRleCA9IGJpbmRpbmdzLmxlbmd0aDtcblx0XHRiaW5kaW5ncy5wdXNoKCBiaW5kaW5nICk7XG5cblx0fSxcblxuXHRfcmVtb3ZlSW5hY3RpdmVCaW5kaW5nOiBmdW5jdGlvbiAoIGJpbmRpbmcgKSB7XG5cblx0XHR2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5ncyxcblx0XHRcdHByb3BCaW5kaW5nID0gYmluZGluZy5iaW5kaW5nLFxuXHRcdFx0cm9vdFV1aWQgPSBwcm9wQmluZGluZy5yb290Tm9kZS51dWlkLFxuXHRcdFx0dHJhY2tOYW1lID0gcHJvcEJpbmRpbmcucGF0aCxcblx0XHRcdGJpbmRpbmdzQnlSb290ID0gdGhpcy5fYmluZGluZ3NCeVJvb3RBbmROYW1lLFxuXHRcdFx0YmluZGluZ0J5TmFtZSA9IGJpbmRpbmdzQnlSb290WyByb290VXVpZCBdLFxuXG5cdFx0XHRsYXN0SW5hY3RpdmVCaW5kaW5nID0gYmluZGluZ3NbIGJpbmRpbmdzLmxlbmd0aCAtIDEgXSxcblx0XHRcdGNhY2hlSW5kZXggPSBiaW5kaW5nLl9jYWNoZUluZGV4O1xuXG5cdFx0bGFzdEluYWN0aXZlQmluZGluZy5fY2FjaGVJbmRleCA9IGNhY2hlSW5kZXg7XG5cdFx0YmluZGluZ3NbIGNhY2hlSW5kZXggXSA9IGxhc3RJbmFjdGl2ZUJpbmRpbmc7XG5cdFx0YmluZGluZ3MucG9wKCk7XG5cblx0XHRkZWxldGUgYmluZGluZ0J5TmFtZVsgdHJhY2tOYW1lIF07XG5cblx0XHRyZW1vdmVfZW1wdHlfbWFwOiB7XG5cblx0XHRcdGZvciAoIHZhciBfIGluIGJpbmRpbmdCeU5hbWUgKSBicmVhayByZW1vdmVfZW1wdHlfbWFwO1xuXG5cdFx0XHRkZWxldGUgYmluZGluZ3NCeVJvb3RbIHJvb3RVdWlkIF07XG5cblx0XHR9XG5cblx0fSxcblxuXHRfbGVuZEJpbmRpbmc6IGZ1bmN0aW9uICggYmluZGluZyApIHtcblxuXHRcdHZhciBiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdzLFxuXHRcdFx0cHJldkluZGV4ID0gYmluZGluZy5fY2FjaGVJbmRleCxcblxuXHRcdFx0bGFzdEFjdGl2ZUluZGV4ID0gdGhpcy5fbkFjdGl2ZUJpbmRpbmdzICsrLFxuXG5cdFx0XHRmaXJzdEluYWN0aXZlQmluZGluZyA9IGJpbmRpbmdzWyBsYXN0QWN0aXZlSW5kZXggXTtcblxuXHRcdGJpbmRpbmcuX2NhY2hlSW5kZXggPSBsYXN0QWN0aXZlSW5kZXg7XG5cdFx0YmluZGluZ3NbIGxhc3RBY3RpdmVJbmRleCBdID0gYmluZGluZztcblxuXHRcdGZpcnN0SW5hY3RpdmVCaW5kaW5nLl9jYWNoZUluZGV4ID0gcHJldkluZGV4O1xuXHRcdGJpbmRpbmdzWyBwcmV2SW5kZXggXSA9IGZpcnN0SW5hY3RpdmVCaW5kaW5nO1xuXG5cdH0sXG5cblx0X3Rha2VCYWNrQmluZGluZzogZnVuY3Rpb24gKCBiaW5kaW5nICkge1xuXG5cdFx0dmFyIGJpbmRpbmdzID0gdGhpcy5fYmluZGluZ3MsXG5cdFx0XHRwcmV2SW5kZXggPSBiaW5kaW5nLl9jYWNoZUluZGV4LFxuXG5cdFx0XHRmaXJzdEluYWN0aXZlSW5kZXggPSAtLSB0aGlzLl9uQWN0aXZlQmluZGluZ3MsXG5cblx0XHRcdGxhc3RBY3RpdmVCaW5kaW5nID0gYmluZGluZ3NbIGZpcnN0SW5hY3RpdmVJbmRleCBdO1xuXG5cdFx0YmluZGluZy5fY2FjaGVJbmRleCA9IGZpcnN0SW5hY3RpdmVJbmRleDtcblx0XHRiaW5kaW5nc1sgZmlyc3RJbmFjdGl2ZUluZGV4IF0gPSBiaW5kaW5nO1xuXG5cdFx0bGFzdEFjdGl2ZUJpbmRpbmcuX2NhY2hlSW5kZXggPSBwcmV2SW5kZXg7XG5cdFx0YmluZGluZ3NbIHByZXZJbmRleCBdID0gbGFzdEFjdGl2ZUJpbmRpbmc7XG5cblx0fSxcblxuXG5cdC8vIE1lbW9yeSBtYW5hZ2VtZW50IG9mIEludGVycG9sYW50cyBmb3Igd2VpZ2h0IGFuZCB0aW1lIHNjYWxlXG5cblx0X2xlbmRDb250cm9sSW50ZXJwb2xhbnQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBpbnRlcnBvbGFudHMgPSB0aGlzLl9jb250cm9sSW50ZXJwb2xhbnRzLFxuXHRcdFx0bGFzdEFjdGl2ZUluZGV4ID0gdGhpcy5fbkFjdGl2ZUNvbnRyb2xJbnRlcnBvbGFudHMgKyssXG5cdFx0XHRpbnRlcnBvbGFudCA9IGludGVycG9sYW50c1sgbGFzdEFjdGl2ZUluZGV4IF07XG5cblx0XHRpZiAoIGludGVycG9sYW50ID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGludGVycG9sYW50ID0gbmV3IExpbmVhckludGVycG9sYW50KFxuXHRcdFx0XHRuZXcgRmxvYXQzMkFycmF5KCAyICksIG5ldyBGbG9hdDMyQXJyYXkoIDIgKSxcblx0XHRcdFx0MSwgdGhpcy5fY29udHJvbEludGVycG9sYW50c1Jlc3VsdEJ1ZmZlciApO1xuXG5cdFx0XHRpbnRlcnBvbGFudC5fX2NhY2hlSW5kZXggPSBsYXN0QWN0aXZlSW5kZXg7XG5cdFx0XHRpbnRlcnBvbGFudHNbIGxhc3RBY3RpdmVJbmRleCBdID0gaW50ZXJwb2xhbnQ7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gaW50ZXJwb2xhbnQ7XG5cblx0fSxcblxuXHRfdGFrZUJhY2tDb250cm9sSW50ZXJwb2xhbnQ6IGZ1bmN0aW9uICggaW50ZXJwb2xhbnQgKSB7XG5cblx0XHR2YXIgaW50ZXJwb2xhbnRzID0gdGhpcy5fY29udHJvbEludGVycG9sYW50cyxcblx0XHRcdHByZXZJbmRleCA9IGludGVycG9sYW50Ll9fY2FjaGVJbmRleCxcblxuXHRcdFx0Zmlyc3RJbmFjdGl2ZUluZGV4ID0gLS0gdGhpcy5fbkFjdGl2ZUNvbnRyb2xJbnRlcnBvbGFudHMsXG5cblx0XHRcdGxhc3RBY3RpdmVJbnRlcnBvbGFudCA9IGludGVycG9sYW50c1sgZmlyc3RJbmFjdGl2ZUluZGV4IF07XG5cblx0XHRpbnRlcnBvbGFudC5fX2NhY2hlSW5kZXggPSBmaXJzdEluYWN0aXZlSW5kZXg7XG5cdFx0aW50ZXJwb2xhbnRzWyBmaXJzdEluYWN0aXZlSW5kZXggXSA9IGludGVycG9sYW50O1xuXG5cdFx0bGFzdEFjdGl2ZUludGVycG9sYW50Ll9fY2FjaGVJbmRleCA9IHByZXZJbmRleDtcblx0XHRpbnRlcnBvbGFudHNbIHByZXZJbmRleCBdID0gbGFzdEFjdGl2ZUludGVycG9sYW50O1xuXG5cdH0sXG5cblx0X2NvbnRyb2xJbnRlcnBvbGFudHNSZXN1bHRCdWZmZXI6IG5ldyBGbG9hdDMyQXJyYXkoIDEgKSxcblxuXHQvLyByZXR1cm4gYW4gYWN0aW9uIGZvciBhIGNsaXAgb3B0aW9uYWxseSB1c2luZyBhIGN1c3RvbSByb290IHRhcmdldFxuXHQvLyBvYmplY3QgKHRoaXMgbWV0aG9kIGFsbG9jYXRlcyBhIGxvdCBvZiBkeW5hbWljIG1lbW9yeSBpbiBjYXNlIGFcblx0Ly8gcHJldmlvdXNseSB1bmtub3duIGNsaXAvcm9vdCBjb21iaW5hdGlvbiBpcyBzcGVjaWZpZWQpXG5cdGNsaXBBY3Rpb246IGZ1bmN0aW9uICggY2xpcCwgb3B0aW9uYWxSb290ICkge1xuXG5cdFx0dmFyIHJvb3QgPSBvcHRpb25hbFJvb3QgfHwgdGhpcy5fcm9vdCxcblx0XHRcdHJvb3RVdWlkID0gcm9vdC51dWlkLFxuXG5cdFx0XHRjbGlwT2JqZWN0ID0gdHlwZW9mIGNsaXAgPT09ICdzdHJpbmcnID9cblx0XHRcdFx0QW5pbWF0aW9uQ2xpcC5maW5kQnlOYW1lKCByb290LCBjbGlwICkgOiBjbGlwLFxuXG5cdFx0XHRjbGlwVXVpZCA9IGNsaXBPYmplY3QgIT09IG51bGwgPyBjbGlwT2JqZWN0LnV1aWQgOiBjbGlwLFxuXG5cdFx0XHRhY3Rpb25zRm9yQ2xpcCA9IHRoaXMuX2FjdGlvbnNCeUNsaXBbIGNsaXBVdWlkIF0sXG5cdFx0XHRwcm90b3R5cGVBY3Rpb24gPSBudWxsO1xuXG5cdFx0aWYgKCBhY3Rpb25zRm9yQ2xpcCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHR2YXIgZXhpc3RpbmdBY3Rpb24gPVxuXHRcdFx0XHRcdGFjdGlvbnNGb3JDbGlwLmFjdGlvbkJ5Um9vdFsgcm9vdFV1aWQgXTtcblxuXHRcdFx0aWYgKCBleGlzdGluZ0FjdGlvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiBleGlzdGluZ0FjdGlvbjtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyB3ZSBrbm93IHRoZSBjbGlwLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHBhcnNlIGFsbFxuXHRcdFx0Ly8gdGhlIGJpbmRpbmdzIGFnYWluIGJ1dCBjYW4ganVzdCBjb3B5XG5cdFx0XHRwcm90b3R5cGVBY3Rpb24gPSBhY3Rpb25zRm9yQ2xpcC5rbm93bkFjdGlvbnNbIDAgXTtcblxuXHRcdFx0Ly8gYWxzbywgdGFrZSB0aGUgY2xpcCBmcm9tIHRoZSBwcm90b3R5cGUgYWN0aW9uXG5cdFx0XHRpZiAoIGNsaXBPYmplY3QgPT09IG51bGwgKVxuXHRcdFx0XHRjbGlwT2JqZWN0ID0gcHJvdG90eXBlQWN0aW9uLl9jbGlwO1xuXG5cdFx0fVxuXG5cdFx0Ly8gY2xpcCBtdXN0IGJlIGtub3duIHdoZW4gc3BlY2lmaWVkIHZpYSBzdHJpbmdcblx0XHRpZiAoIGNsaXBPYmplY3QgPT09IG51bGwgKSByZXR1cm4gbnVsbDtcblxuXHRcdC8vIGFsbG9jYXRlIGFsbCByZXNvdXJjZXMgcmVxdWlyZWQgdG8gcnVuIGl0XG5cdFx0dmFyIG5ld0FjdGlvbiA9IG5ldyBBbmltYXRpb25BY3Rpb24oIHRoaXMsIGNsaXBPYmplY3QsIG9wdGlvbmFsUm9vdCApO1xuXG5cdFx0dGhpcy5fYmluZEFjdGlvbiggbmV3QWN0aW9uLCBwcm90b3R5cGVBY3Rpb24gKTtcblxuXHRcdC8vIGFuZCBtYWtlIHRoZSBhY3Rpb24ga25vd24gdG8gdGhlIG1lbW9yeSBtYW5hZ2VyXG5cdFx0dGhpcy5fYWRkSW5hY3RpdmVBY3Rpb24oIG5ld0FjdGlvbiwgY2xpcFV1aWQsIHJvb3RVdWlkICk7XG5cblx0XHRyZXR1cm4gbmV3QWN0aW9uO1xuXG5cdH0sXG5cblx0Ly8gZ2V0IGFuIGV4aXN0aW5nIGFjdGlvblxuXHRleGlzdGluZ0FjdGlvbjogZnVuY3Rpb24gKCBjbGlwLCBvcHRpb25hbFJvb3QgKSB7XG5cblx0XHR2YXIgcm9vdCA9IG9wdGlvbmFsUm9vdCB8fCB0aGlzLl9yb290LFxuXHRcdFx0cm9vdFV1aWQgPSByb290LnV1aWQsXG5cblx0XHRcdGNsaXBPYmplY3QgPSB0eXBlb2YgY2xpcCA9PT0gJ3N0cmluZycgP1xuXHRcdFx0XHRBbmltYXRpb25DbGlwLmZpbmRCeU5hbWUoIHJvb3QsIGNsaXAgKSA6IGNsaXAsXG5cblx0XHRcdGNsaXBVdWlkID0gY2xpcE9iamVjdCA/IGNsaXBPYmplY3QudXVpZCA6IGNsaXAsXG5cblx0XHRcdGFjdGlvbnNGb3JDbGlwID0gdGhpcy5fYWN0aW9uc0J5Q2xpcFsgY2xpcFV1aWQgXTtcblxuXHRcdGlmICggYWN0aW9uc0ZvckNsaXAgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0cmV0dXJuIGFjdGlvbnNGb3JDbGlwLmFjdGlvbkJ5Um9vdFsgcm9vdFV1aWQgXSB8fCBudWxsO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cblx0fSxcblxuXHQvLyBkZWFjdGl2YXRlcyBhbGwgcHJldmlvdXNseSBzY2hlZHVsZWQgYWN0aW9uc1xuXHRzdG9wQWxsQWN0aW9uOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgYWN0aW9ucyA9IHRoaXMuX2FjdGlvbnMsXG5cdFx0XHRuQWN0aW9ucyA9IHRoaXMuX25BY3RpdmVBY3Rpb25zLFxuXHRcdFx0YmluZGluZ3MgPSB0aGlzLl9iaW5kaW5ncyxcblx0XHRcdG5CaW5kaW5ncyA9IHRoaXMuX25BY3RpdmVCaW5kaW5ncztcblxuXHRcdHRoaXMuX25BY3RpdmVBY3Rpb25zID0gMDtcblx0XHR0aGlzLl9uQWN0aXZlQmluZGluZ3MgPSAwO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuQWN0aW9uczsgKysgaSApIHtcblxuXHRcdFx0YWN0aW9uc1sgaSBdLnJlc2V0KCk7XG5cblx0XHR9XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgIT09IG5CaW5kaW5nczsgKysgaSApIHtcblxuXHRcdFx0YmluZGluZ3NbIGkgXS51c2VDb3VudCA9IDA7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdC8vIGFkdmFuY2UgdGhlIHRpbWUgYW5kIHVwZGF0ZSBhcHBseSB0aGUgYW5pbWF0aW9uXG5cdHVwZGF0ZTogZnVuY3Rpb24gKCBkZWx0YVRpbWUgKSB7XG5cblx0XHRkZWx0YVRpbWUgKj0gdGhpcy50aW1lU2NhbGU7XG5cblx0XHR2YXIgYWN0aW9ucyA9IHRoaXMuX2FjdGlvbnMsXG5cdFx0XHRuQWN0aW9ucyA9IHRoaXMuX25BY3RpdmVBY3Rpb25zLFxuXG5cdFx0XHR0aW1lID0gdGhpcy50aW1lICs9IGRlbHRhVGltZSxcblx0XHRcdHRpbWVEaXJlY3Rpb24gPSBNYXRoLnNpZ24oIGRlbHRhVGltZSApLFxuXG5cdFx0XHRhY2N1SW5kZXggPSB0aGlzLl9hY2N1SW5kZXggXj0gMTtcblxuXHRcdC8vIHJ1biBhY3RpdmUgYWN0aW9uc1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuQWN0aW9uczsgKysgaSApIHtcblxuXHRcdFx0dmFyIGFjdGlvbiA9IGFjdGlvbnNbIGkgXTtcblxuXHRcdFx0YWN0aW9uLl91cGRhdGUoIHRpbWUsIGRlbHRhVGltZSwgdGltZURpcmVjdGlvbiwgYWNjdUluZGV4ICk7XG5cblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgc2NlbmUgZ3JhcGhcblxuXHRcdHZhciBiaW5kaW5ncyA9IHRoaXMuX2JpbmRpbmdzLFxuXHRcdFx0bkJpbmRpbmdzID0gdGhpcy5fbkFjdGl2ZUJpbmRpbmdzO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpICE9PSBuQmluZGluZ3M7ICsrIGkgKSB7XG5cblx0XHRcdGJpbmRpbmdzWyBpIF0uYXBwbHkoIGFjY3VJbmRleCApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHQvLyByZXR1cm4gdGhpcyBtaXhlcidzIHJvb3QgdGFyZ2V0IG9iamVjdFxuXHRnZXRSb290OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5fcm9vdDtcblxuXHR9LFxuXG5cdC8vIGZyZWUgYWxsIHJlc291cmNlcyBzcGVjaWZpYyB0byBhIHBhcnRpY3VsYXIgY2xpcFxuXHR1bmNhY2hlQ2xpcDogZnVuY3Rpb24gKCBjbGlwICkge1xuXG5cdFx0dmFyIGFjdGlvbnMgPSB0aGlzLl9hY3Rpb25zLFxuXHRcdFx0Y2xpcFV1aWQgPSBjbGlwLnV1aWQsXG5cdFx0XHRhY3Rpb25zQnlDbGlwID0gdGhpcy5fYWN0aW9uc0J5Q2xpcCxcblx0XHRcdGFjdGlvbnNGb3JDbGlwID0gYWN0aW9uc0J5Q2xpcFsgY2xpcFV1aWQgXTtcblxuXHRcdGlmICggYWN0aW9uc0ZvckNsaXAgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gbm90ZToganVzdCBjYWxsaW5nIF9yZW1vdmVJbmFjdGl2ZUFjdGlvbiB3b3VsZCBtZXNzIHVwIHRoZVxuXHRcdFx0Ly8gaXRlcmF0aW9uIHN0YXRlIGFuZCBhbHNvIHJlcXVpcmUgdXBkYXRpbmcgdGhlIHN0YXRlIHdlIGNhblxuXHRcdFx0Ly8ganVzdCB0aHJvdyBhd2F5XG5cblx0XHRcdHZhciBhY3Rpb25zVG9SZW1vdmUgPSBhY3Rpb25zRm9yQ2xpcC5rbm93bkFjdGlvbnM7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbiA9IGFjdGlvbnNUb1JlbW92ZS5sZW5ndGg7IGkgIT09IG47ICsrIGkgKSB7XG5cblx0XHRcdFx0dmFyIGFjdGlvbiA9IGFjdGlvbnNUb1JlbW92ZVsgaSBdO1xuXG5cdFx0XHRcdHRoaXMuX2RlYWN0aXZhdGVBY3Rpb24oIGFjdGlvbiApO1xuXG5cdFx0XHRcdHZhciBjYWNoZUluZGV4ID0gYWN0aW9uLl9jYWNoZUluZGV4LFxuXHRcdFx0XHRcdGxhc3RJbmFjdGl2ZUFjdGlvbiA9IGFjdGlvbnNbIGFjdGlvbnMubGVuZ3RoIC0gMSBdO1xuXG5cdFx0XHRcdGFjdGlvbi5fY2FjaGVJbmRleCA9IG51bGw7XG5cdFx0XHRcdGFjdGlvbi5fYnlDbGlwQ2FjaGVJbmRleCA9IG51bGw7XG5cblx0XHRcdFx0bGFzdEluYWN0aXZlQWN0aW9uLl9jYWNoZUluZGV4ID0gY2FjaGVJbmRleDtcblx0XHRcdFx0YWN0aW9uc1sgY2FjaGVJbmRleCBdID0gbGFzdEluYWN0aXZlQWN0aW9uO1xuXHRcdFx0XHRhY3Rpb25zLnBvcCgpO1xuXG5cdFx0XHRcdHRoaXMuX3JlbW92ZUluYWN0aXZlQmluZGluZ3NGb3JBY3Rpb24oIGFjdGlvbiApO1xuXG5cdFx0XHR9XG5cblx0XHRcdGRlbGV0ZSBhY3Rpb25zQnlDbGlwWyBjbGlwVXVpZCBdO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gZnJlZSBhbGwgcmVzb3VyY2VzIHNwZWNpZmljIHRvIGEgcGFydGljdWxhciByb290IHRhcmdldCBvYmplY3Rcblx0dW5jYWNoZVJvb3Q6IGZ1bmN0aW9uICggcm9vdCApIHtcblxuXHRcdHZhciByb290VXVpZCA9IHJvb3QudXVpZCxcblx0XHRcdGFjdGlvbnNCeUNsaXAgPSB0aGlzLl9hY3Rpb25zQnlDbGlwO1xuXG5cdFx0Zm9yICggdmFyIGNsaXBVdWlkIGluIGFjdGlvbnNCeUNsaXAgKSB7XG5cblx0XHRcdHZhciBhY3Rpb25CeVJvb3QgPSBhY3Rpb25zQnlDbGlwWyBjbGlwVXVpZCBdLmFjdGlvbkJ5Um9vdCxcblx0XHRcdFx0YWN0aW9uID0gYWN0aW9uQnlSb290WyByb290VXVpZCBdO1xuXG5cdFx0XHRpZiAoIGFjdGlvbiAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHRoaXMuX2RlYWN0aXZhdGVBY3Rpb24oIGFjdGlvbiApO1xuXHRcdFx0XHR0aGlzLl9yZW1vdmVJbmFjdGl2ZUFjdGlvbiggYWN0aW9uICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHZhciBiaW5kaW5nc0J5Um9vdCA9IHRoaXMuX2JpbmRpbmdzQnlSb290QW5kTmFtZSxcblx0XHRcdGJpbmRpbmdCeU5hbWUgPSBiaW5kaW5nc0J5Um9vdFsgcm9vdFV1aWQgXTtcblxuXHRcdGlmICggYmluZGluZ0J5TmFtZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRmb3IgKCB2YXIgdHJhY2tOYW1lIGluIGJpbmRpbmdCeU5hbWUgKSB7XG5cblx0XHRcdFx0dmFyIGJpbmRpbmcgPSBiaW5kaW5nQnlOYW1lWyB0cmFja05hbWUgXTtcblx0XHRcdFx0YmluZGluZy5yZXN0b3JlT3JpZ2luYWxTdGF0ZSgpO1xuXHRcdFx0XHR0aGlzLl9yZW1vdmVJbmFjdGl2ZUJpbmRpbmcoIGJpbmRpbmcgKTtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gcmVtb3ZlIGEgdGFyZ2V0ZWQgY2xpcCBmcm9tIHRoZSBjYWNoZVxuXHR1bmNhY2hlQWN0aW9uOiBmdW5jdGlvbiAoIGNsaXAsIG9wdGlvbmFsUm9vdCApIHtcblxuXHRcdHZhciBhY3Rpb24gPSB0aGlzLmV4aXN0aW5nQWN0aW9uKCBjbGlwLCBvcHRpb25hbFJvb3QgKTtcblxuXHRcdGlmICggYWN0aW9uICE9PSBudWxsICkge1xuXG5cdFx0XHR0aGlzLl9kZWFjdGl2YXRlQWN0aW9uKCBhY3Rpb24gKTtcblx0XHRcdHRoaXMuX3JlbW92ZUluYWN0aXZlQWN0aW9uKCBhY3Rpb24gKTtcblxuXHRcdH1cblxuXHR9XG5cbn0gKTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIFVuaWZvcm0oIHZhbHVlICkge1xuXG5cdGlmICggdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlVuaWZvcm06IFR5cGUgcGFyYW1ldGVyIGlzIG5vIGxvbmdlciBuZWVkZWQuJyApO1xuXHRcdHZhbHVlID0gYXJndW1lbnRzWyAxIF07XG5cblx0fVxuXG5cdHRoaXMudmFsdWUgPSB2YWx1ZTtcblxufVxuXG5Vbmlmb3JtLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcblxuXHRyZXR1cm4gbmV3IFVuaWZvcm0oIHRoaXMudmFsdWUuY2xvbmUgPT09IHVuZGVmaW5lZCA/IHRoaXMudmFsdWUgOiB0aGlzLnZhbHVlLmNsb25lKCkgKTtcblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIGJlbmFhZGFtcyAvIGh0dHBzOi8vdHdpdHRlci5jb20vYmVuX2FfYWRhbXNcbiAqL1xuXG5mdW5jdGlvbiBJbnN0YW5jZWRCdWZmZXJHZW9tZXRyeSgpIHtcblxuXHRCdWZmZXJHZW9tZXRyeS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy50eXBlID0gJ0luc3RhbmNlZEJ1ZmZlckdlb21ldHJ5Jztcblx0dGhpcy5tYXhJbnN0YW5jZWRDb3VudCA9IHVuZGVmaW5lZDtcblxufVxuXG5JbnN0YW5jZWRCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBCdWZmZXJHZW9tZXRyeS5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBJbnN0YW5jZWRCdWZmZXJHZW9tZXRyeSxcblxuXHRpc0luc3RhbmNlZEJ1ZmZlckdlb21ldHJ5OiB0cnVlLFxuXG5cdGFkZEdyb3VwOiBmdW5jdGlvbiAoIHN0YXJ0LCBjb3VudCwgbWF0ZXJpYWxJbmRleCApIHtcblxuXHRcdHRoaXMuZ3JvdXBzLnB1c2goIHtcblxuXHRcdFx0c3RhcnQ6IHN0YXJ0LFxuXHRcdFx0Y291bnQ6IGNvdW50LFxuXHRcdFx0bWF0ZXJpYWxJbmRleDogbWF0ZXJpYWxJbmRleFxuXG5cdFx0fSApO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR2YXIgaW5kZXggPSBzb3VyY2UuaW5kZXg7XG5cblx0XHRpZiAoIGluZGV4ICE9PSBudWxsICkge1xuXG5cdFx0XHR0aGlzLnNldEluZGV4KCBpbmRleC5jbG9uZSgpICk7XG5cblx0XHR9XG5cblx0XHR2YXIgYXR0cmlidXRlcyA9IHNvdXJjZS5hdHRyaWJ1dGVzO1xuXG5cdFx0Zm9yICggdmFyIG5hbWUgaW4gYXR0cmlidXRlcyApIHtcblxuXHRcdFx0dmFyIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXNbIG5hbWUgXTtcblx0XHRcdHRoaXMuYWRkQXR0cmlidXRlKCBuYW1lLCBhdHRyaWJ1dGUuY2xvbmUoKSApO1xuXG5cdFx0fVxuXG5cdFx0dmFyIGdyb3VwcyA9IHNvdXJjZS5ncm91cHM7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBncm91cHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGdyb3VwID0gZ3JvdXBzWyBpIF07XG5cdFx0XHR0aGlzLmFkZEdyb3VwKCBncm91cC5zdGFydCwgZ3JvdXAuY291bnQsIGdyb3VwLm1hdGVyaWFsSW5kZXggKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYmVuYWFkYW1zIC8gaHR0cHM6Ly90d2l0dGVyLmNvbS9iZW5fYV9hZGFtc1xuICovXG5cbmZ1bmN0aW9uIEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlKCBpbnRlcmxlYXZlZEJ1ZmZlciwgaXRlbVNpemUsIG9mZnNldCwgbm9ybWFsaXplZCApIHtcblxuXHR0aGlzLnV1aWQgPSBfTWF0aC5nZW5lcmF0ZVVVSUQoKTtcblxuXHR0aGlzLmRhdGEgPSBpbnRlcmxlYXZlZEJ1ZmZlcjtcblx0dGhpcy5pdGVtU2l6ZSA9IGl0ZW1TaXplO1xuXHR0aGlzLm9mZnNldCA9IG9mZnNldDtcblxuXHR0aGlzLm5vcm1hbGl6ZWQgPSBub3JtYWxpemVkID09PSB0cnVlO1xuXG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUsIHtcblxuXHRjb3VudDoge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLmRhdGEuY291bnQ7XG5cblx0XHR9XG5cblx0fSxcblxuXHRhcnJheToge1xuXG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLmRhdGEuYXJyYXk7XG5cblx0XHR9XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIEludGVybGVhdmVkQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSwge1xuXG5cdGlzSW50ZXJsZWF2ZWRCdWZmZXJBdHRyaWJ1dGU6IHRydWUsXG5cblx0c2V0WDogZnVuY3Rpb24gKCBpbmRleCwgeCApIHtcblxuXHRcdHRoaXMuZGF0YS5hcnJheVsgaW5kZXggKiB0aGlzLmRhdGEuc3RyaWRlICsgdGhpcy5vZmZzZXQgXSA9IHg7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFk6IGZ1bmN0aW9uICggaW5kZXgsIHkgKSB7XG5cblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICogdGhpcy5kYXRhLnN0cmlkZSArIHRoaXMub2Zmc2V0ICsgMSBdID0geTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0WjogZnVuY3Rpb24gKCBpbmRleCwgeiApIHtcblxuXHRcdHRoaXMuZGF0YS5hcnJheVsgaW5kZXggKiB0aGlzLmRhdGEuc3RyaWRlICsgdGhpcy5vZmZzZXQgKyAyIF0gPSB6O1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHRzZXRXOiBmdW5jdGlvbiAoIGluZGV4LCB3ICkge1xuXG5cdFx0dGhpcy5kYXRhLmFycmF5WyBpbmRleCAqIHRoaXMuZGF0YS5zdHJpZGUgKyB0aGlzLm9mZnNldCArIDMgXSA9IHc7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGdldFg6IGZ1bmN0aW9uICggaW5kZXggKSB7XG5cblx0XHRyZXR1cm4gdGhpcy5kYXRhLmFycmF5WyBpbmRleCAqIHRoaXMuZGF0YS5zdHJpZGUgKyB0aGlzLm9mZnNldCBdO1xuXG5cdH0sXG5cblx0Z2V0WTogZnVuY3Rpb24gKCBpbmRleCApIHtcblxuXHRcdHJldHVybiB0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICogdGhpcy5kYXRhLnN0cmlkZSArIHRoaXMub2Zmc2V0ICsgMSBdO1xuXG5cdH0sXG5cblx0Z2V0WjogZnVuY3Rpb24gKCBpbmRleCApIHtcblxuXHRcdHJldHVybiB0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICogdGhpcy5kYXRhLnN0cmlkZSArIHRoaXMub2Zmc2V0ICsgMiBdO1xuXG5cdH0sXG5cblx0Z2V0VzogZnVuY3Rpb24gKCBpbmRleCApIHtcblxuXHRcdHJldHVybiB0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICogdGhpcy5kYXRhLnN0cmlkZSArIHRoaXMub2Zmc2V0ICsgMyBdO1xuXG5cdH0sXG5cblx0c2V0WFk6IGZ1bmN0aW9uICggaW5kZXgsIHgsIHkgKSB7XG5cblx0XHRpbmRleCA9IGluZGV4ICogdGhpcy5kYXRhLnN0cmlkZSArIHRoaXMub2Zmc2V0O1xuXG5cdFx0dGhpcy5kYXRhLmFycmF5WyBpbmRleCArIDAgXSA9IHg7XG5cdFx0dGhpcy5kYXRhLmFycmF5WyBpbmRleCArIDEgXSA9IHk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldFhZWjogZnVuY3Rpb24gKCBpbmRleCwgeCwgeSwgeiApIHtcblxuXHRcdGluZGV4ID0gaW5kZXggKiB0aGlzLmRhdGEuc3RyaWRlICsgdGhpcy5vZmZzZXQ7XG5cblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMCBdID0geDtcblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMSBdID0geTtcblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMiBdID0gejtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0WFlaVzogZnVuY3Rpb24gKCBpbmRleCwgeCwgeSwgeiwgdyApIHtcblxuXHRcdGluZGV4ID0gaW5kZXggKiB0aGlzLmRhdGEuc3RyaWRlICsgdGhpcy5vZmZzZXQ7XG5cblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMCBdID0geDtcblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMSBdID0geTtcblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMiBdID0gejtcblx0XHR0aGlzLmRhdGEuYXJyYXlbIGluZGV4ICsgMyBdID0gdztcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYmVuYWFkYW1zIC8gaHR0cHM6Ly90d2l0dGVyLmNvbS9iZW5fYV9hZGFtc1xuICovXG5cbmZ1bmN0aW9uIEludGVybGVhdmVkQnVmZmVyKCBhcnJheSwgc3RyaWRlICkge1xuXG5cdHRoaXMudXVpZCA9IF9NYXRoLmdlbmVyYXRlVVVJRCgpO1xuXG5cdHRoaXMuYXJyYXkgPSBhcnJheTtcblx0dGhpcy5zdHJpZGUgPSBzdHJpZGU7XG5cdHRoaXMuY291bnQgPSBhcnJheSAhPT0gdW5kZWZpbmVkID8gYXJyYXkubGVuZ3RoIC8gc3RyaWRlIDogMDtcblxuXHR0aGlzLmR5bmFtaWMgPSBmYWxzZTtcblx0dGhpcy51cGRhdGVSYW5nZSA9IHsgb2Zmc2V0OiAwLCBjb3VudDogLSAxIH07XG5cblx0dGhpcy5vblVwbG9hZENhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG5cblx0dGhpcy52ZXJzaW9uID0gMDtcblxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoIEludGVybGVhdmVkQnVmZmVyLnByb3RvdHlwZSwgJ25lZWRzVXBkYXRlJywge1xuXG5cdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdGlmICggdmFsdWUgPT09IHRydWUgKSB0aGlzLnZlcnNpb24gKys7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIEludGVybGVhdmVkQnVmZmVyLnByb3RvdHlwZSwge1xuXG5cdGlzSW50ZXJsZWF2ZWRCdWZmZXI6IHRydWUsXG5cblx0c2V0QXJyYXk6IGZ1bmN0aW9uICggYXJyYXkgKSB7XG5cblx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIGFycmF5ICkgKSB7XG5cblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoICdUSFJFRS5CdWZmZXJBdHRyaWJ1dGU6IGFycmF5IHNob3VsZCBiZSBhIFR5cGVkIEFycmF5LicgKTtcblxuXHRcdH1cblxuXHRcdHRoaXMuY291bnQgPSBhcnJheSAhPT0gdW5kZWZpbmVkID8gYXJyYXkubGVuZ3RoIC8gdGhpcy5zdHJpZGUgOiAwO1xuXHRcdHRoaXMuYXJyYXkgPSBhcnJheTtcblxuXHR9LFxuXG5cdHNldER5bmFtaWM6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHR0aGlzLmR5bmFtaWMgPSB2YWx1ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHR0aGlzLmFycmF5ID0gbmV3IHNvdXJjZS5hcnJheS5jb25zdHJ1Y3Rvciggc291cmNlLmFycmF5ICk7XG5cdFx0dGhpcy5jb3VudCA9IHNvdXJjZS5jb3VudDtcblx0XHR0aGlzLnN0cmlkZSA9IHNvdXJjZS5zdHJpZGU7XG5cdFx0dGhpcy5keW5hbWljID0gc291cmNlLmR5bmFtaWM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNvcHlBdDogZnVuY3Rpb24gKCBpbmRleDEsIGF0dHJpYnV0ZSwgaW5kZXgyICkge1xuXG5cdFx0aW5kZXgxICo9IHRoaXMuc3RyaWRlO1xuXHRcdGluZGV4MiAqPSBhdHRyaWJ1dGUuc3RyaWRlO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gdGhpcy5zdHJpZGU7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR0aGlzLmFycmF5WyBpbmRleDEgKyBpIF0gPSBhdHRyaWJ1dGUuYXJyYXlbIGluZGV4MiArIGkgXTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlLCBvZmZzZXQgKSB7XG5cblx0XHRpZiAoIG9mZnNldCA9PT0gdW5kZWZpbmVkICkgb2Zmc2V0ID0gMDtcblxuXHRcdHRoaXMuYXJyYXkuc2V0KCB2YWx1ZSwgb2Zmc2V0ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KCB0aGlzICk7XG5cblx0fSxcblxuXHRvblVwbG9hZDogZnVuY3Rpb24gKCBjYWxsYmFjayApIHtcblxuXHRcdHRoaXMub25VcGxvYWRDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBiZW5hYWRhbXMgLyBodHRwczovL3R3aXR0ZXIuY29tL2Jlbl9hX2FkYW1zXG4gKi9cblxuZnVuY3Rpb24gSW5zdGFuY2VkSW50ZXJsZWF2ZWRCdWZmZXIoIGFycmF5LCBzdHJpZGUsIG1lc2hQZXJBdHRyaWJ1dGUgKSB7XG5cblx0SW50ZXJsZWF2ZWRCdWZmZXIuY2FsbCggdGhpcywgYXJyYXksIHN0cmlkZSApO1xuXG5cdHRoaXMubWVzaFBlckF0dHJpYnV0ZSA9IG1lc2hQZXJBdHRyaWJ1dGUgfHwgMTtcblxufVxuXG5JbnN0YW5jZWRJbnRlcmxlYXZlZEJ1ZmZlci5wcm90b3R5cGUgPSBPYmplY3QuYXNzaWduKCBPYmplY3QuY3JlYXRlKCBJbnRlcmxlYXZlZEJ1ZmZlci5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBJbnN0YW5jZWRJbnRlcmxlYXZlZEJ1ZmZlcixcblxuXHRpc0luc3RhbmNlZEludGVybGVhdmVkQnVmZmVyOiB0cnVlLFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggc291cmNlICkge1xuXG5cdFx0SW50ZXJsZWF2ZWRCdWZmZXIucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLm1lc2hQZXJBdHRyaWJ1dGUgPSBzb3VyY2UubWVzaFBlckF0dHJpYnV0ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgYmVuYWFkYW1zIC8gaHR0cHM6Ly90d2l0dGVyLmNvbS9iZW5fYV9hZGFtc1xuICovXG5cbmZ1bmN0aW9uIEluc3RhbmNlZEJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplLCBtZXNoUGVyQXR0cmlidXRlICkge1xuXG5cdEJ1ZmZlckF0dHJpYnV0ZS5jYWxsKCB0aGlzLCBhcnJheSwgaXRlbVNpemUgKTtcblxuXHR0aGlzLm1lc2hQZXJBdHRyaWJ1dGUgPSBtZXNoUGVyQXR0cmlidXRlIHx8IDE7XG5cbn1cblxuSW5zdGFuY2VkQnVmZmVyQXR0cmlidXRlLnByb3RvdHlwZSA9IE9iamVjdC5hc3NpZ24oIE9iamVjdC5jcmVhdGUoIEJ1ZmZlckF0dHJpYnV0ZS5wcm90b3R5cGUgKSwge1xuXG5cdGNvbnN0cnVjdG9yOiBJbnN0YW5jZWRCdWZmZXJBdHRyaWJ1dGUsXG5cblx0aXNJbnN0YW5jZWRCdWZmZXJBdHRyaWJ1dGU6IHRydWUsXG5cblx0Y29weTogZnVuY3Rpb24gKCBzb3VyY2UgKSB7XG5cblx0XHRCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLmNvcHkuY2FsbCggdGhpcywgc291cmNlICk7XG5cblx0XHR0aGlzLm1lc2hQZXJBdHRyaWJ1dGUgPSBzb3VyY2UubWVzaFBlckF0dHJpYnV0ZTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvL1xuICogQGF1dGhvciBzdGVwaG9taSAvIGh0dHA6Ly9zdGVwaGFuZWdpbmllci5jb20vXG4gKi9cblxuZnVuY3Rpb24gUmF5Y2FzdGVyKCBvcmlnaW4sIGRpcmVjdGlvbiwgbmVhciwgZmFyICkge1xuXG5cdHRoaXMucmF5ID0gbmV3IFJheSggb3JpZ2luLCBkaXJlY3Rpb24gKTtcblx0Ly8gZGlyZWN0aW9uIGlzIGFzc3VtZWQgdG8gYmUgbm9ybWFsaXplZCAoZm9yIGFjY3VyYXRlIGRpc3RhbmNlIGNhbGN1bGF0aW9ucylcblxuXHR0aGlzLm5lYXIgPSBuZWFyIHx8IDA7XG5cdHRoaXMuZmFyID0gZmFyIHx8IEluZmluaXR5O1xuXG5cdHRoaXMucGFyYW1zID0ge1xuXHRcdE1lc2g6IHt9LFxuXHRcdExpbmU6IHt9LFxuXHRcdExPRDoge30sXG5cdFx0UG9pbnRzOiB7IHRocmVzaG9sZDogMSB9LFxuXHRcdFNwcml0ZToge31cblx0fTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydGllcyggdGhpcy5wYXJhbXMsIHtcblx0XHRQb2ludENsb3VkOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuUmF5Y2FzdGVyOiBwYXJhbXMuUG9pbnRDbG91ZCBoYXMgYmVlbiByZW5hbWVkIHRvIHBhcmFtcy5Qb2ludHMuJyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5Qb2ludHM7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG5cbn1cblxuZnVuY3Rpb24gYXNjU29ydCggYSwgYiApIHtcblxuXHRyZXR1cm4gYS5kaXN0YW5jZSAtIGIuZGlzdGFuY2U7XG5cbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0T2JqZWN0KCBvYmplY3QsIHJheWNhc3RlciwgaW50ZXJzZWN0cywgcmVjdXJzaXZlICkge1xuXG5cdGlmICggb2JqZWN0LnZpc2libGUgPT09IGZhbHNlICkgcmV0dXJuO1xuXG5cdG9iamVjdC5yYXljYXN0KCByYXljYXN0ZXIsIGludGVyc2VjdHMgKTtcblxuXHRpZiAoIHJlY3Vyc2l2ZSA9PT0gdHJ1ZSApIHtcblxuXHRcdHZhciBjaGlsZHJlbiA9IG9iamVjdC5jaGlsZHJlbjtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdGludGVyc2VjdE9iamVjdCggY2hpbGRyZW5bIGkgXSwgcmF5Y2FzdGVyLCBpbnRlcnNlY3RzLCB0cnVlICk7XG5cblx0XHR9XG5cblx0fVxuXG59XG5cbk9iamVjdC5hc3NpZ24oIFJheWNhc3Rlci5wcm90b3R5cGUsIHtcblxuXHRsaW5lUHJlY2lzaW9uOiAxLFxuXG5cdHNldDogZnVuY3Rpb24gKCBvcmlnaW4sIGRpcmVjdGlvbiApIHtcblxuXHRcdC8vIGRpcmVjdGlvbiBpcyBhc3N1bWVkIHRvIGJlIG5vcm1hbGl6ZWQgKGZvciBhY2N1cmF0ZSBkaXN0YW5jZSBjYWxjdWxhdGlvbnMpXG5cblx0XHR0aGlzLnJheS5zZXQoIG9yaWdpbiwgZGlyZWN0aW9uICk7XG5cblx0fSxcblxuXHRzZXRGcm9tQ2FtZXJhOiBmdW5jdGlvbiAoIGNvb3JkcywgY2FtZXJhICkge1xuXG5cdFx0aWYgKCAoIGNhbWVyYSAmJiBjYW1lcmEuaXNQZXJzcGVjdGl2ZUNhbWVyYSApICkge1xuXG5cdFx0XHR0aGlzLnJheS5vcmlnaW4uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBjYW1lcmEubWF0cml4V29ybGQgKTtcblx0XHRcdHRoaXMucmF5LmRpcmVjdGlvbi5zZXQoIGNvb3Jkcy54LCBjb29yZHMueSwgMC41ICkudW5wcm9qZWN0KCBjYW1lcmEgKS5zdWIoIHRoaXMucmF5Lm9yaWdpbiApLm5vcm1hbGl6ZSgpO1xuXG5cdFx0fSBlbHNlIGlmICggKCBjYW1lcmEgJiYgY2FtZXJhLmlzT3J0aG9ncmFwaGljQ2FtZXJhICkgKSB7XG5cblx0XHRcdHRoaXMucmF5Lm9yaWdpbi5zZXQoIGNvb3Jkcy54LCBjb29yZHMueSwgKCBjYW1lcmEubmVhciArIGNhbWVyYS5mYXIgKSAvICggY2FtZXJhLm5lYXIgLSBjYW1lcmEuZmFyICkgKS51bnByb2plY3QoIGNhbWVyYSApOyAvLyBzZXQgb3JpZ2luIGluIHBsYW5lIG9mIGNhbWVyYVxuXHRcdFx0dGhpcy5yYXkuZGlyZWN0aW9uLnNldCggMCwgMCwgLSAxICkudHJhbnNmb3JtRGlyZWN0aW9uKCBjYW1lcmEubWF0cml4V29ybGQgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5SYXljYXN0ZXI6IFVuc3VwcG9ydGVkIGNhbWVyYSB0eXBlLicgKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdGludGVyc2VjdE9iamVjdDogZnVuY3Rpb24gKCBvYmplY3QsIHJlY3Vyc2l2ZSApIHtcblxuXHRcdHZhciBpbnRlcnNlY3RzID0gW107XG5cblx0XHRpbnRlcnNlY3RPYmplY3QoIG9iamVjdCwgdGhpcywgaW50ZXJzZWN0cywgcmVjdXJzaXZlICk7XG5cblx0XHRpbnRlcnNlY3RzLnNvcnQoIGFzY1NvcnQgKTtcblxuXHRcdHJldHVybiBpbnRlcnNlY3RzO1xuXG5cdH0sXG5cblx0aW50ZXJzZWN0T2JqZWN0czogZnVuY3Rpb24gKCBvYmplY3RzLCByZWN1cnNpdmUgKSB7XG5cblx0XHR2YXIgaW50ZXJzZWN0cyA9IFtdO1xuXG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCBvYmplY3RzICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5SYXljYXN0ZXIuaW50ZXJzZWN0T2JqZWN0czogb2JqZWN0cyBpcyBub3QgYW4gQXJyYXkuJyApO1xuXHRcdFx0cmV0dXJuIGludGVyc2VjdHM7XG5cblx0XHR9XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBvYmplY3RzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdGludGVyc2VjdE9iamVjdCggb2JqZWN0c1sgaSBdLCB0aGlzLCBpbnRlcnNlY3RzLCByZWN1cnNpdmUgKTtcblxuXHRcdH1cblxuXHRcdGludGVyc2VjdHMuc29ydCggYXNjU29ydCApO1xuXG5cdFx0cmV0dXJuIGludGVyc2VjdHM7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBDbG9jayggYXV0b1N0YXJ0ICkge1xuXG5cdHRoaXMuYXV0b1N0YXJ0ID0gKCBhdXRvU3RhcnQgIT09IHVuZGVmaW5lZCApID8gYXV0b1N0YXJ0IDogdHJ1ZTtcblxuXHR0aGlzLnN0YXJ0VGltZSA9IDA7XG5cdHRoaXMub2xkVGltZSA9IDA7XG5cdHRoaXMuZWxhcHNlZFRpbWUgPSAwO1xuXG5cdHRoaXMucnVubmluZyA9IGZhbHNlO1xuXG59XG5cbk9iamVjdC5hc3NpZ24oIENsb2NrLnByb3RvdHlwZSwge1xuXG5cdHN0YXJ0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHR0aGlzLnN0YXJ0VGltZSA9ICggdHlwZW9mIHBlcmZvcm1hbmNlID09PSAndW5kZWZpbmVkJyA/IERhdGUgOiBwZXJmb3JtYW5jZSApLm5vdygpOyAvLyBzZWUgIzEwNzMyXG5cblx0XHR0aGlzLm9sZFRpbWUgPSB0aGlzLnN0YXJ0VGltZTtcblx0XHR0aGlzLmVsYXBzZWRUaW1lID0gMDtcblx0XHR0aGlzLnJ1bm5pbmcgPSB0cnVlO1xuXG5cdH0sXG5cblx0c3RvcDogZnVuY3Rpb24gKCkge1xuXG5cdFx0dGhpcy5nZXRFbGFwc2VkVGltZSgpO1xuXHRcdHRoaXMucnVubmluZyA9IGZhbHNlO1xuXG5cdH0sXG5cblx0Z2V0RWxhcHNlZFRpbWU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHRoaXMuZ2V0RGVsdGEoKTtcblx0XHRyZXR1cm4gdGhpcy5lbGFwc2VkVGltZTtcblxuXHR9LFxuXG5cdGdldERlbHRhOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgZGlmZiA9IDA7XG5cblx0XHRpZiAoIHRoaXMuYXV0b1N0YXJ0ICYmICEgdGhpcy5ydW5uaW5nICkge1xuXG5cdFx0XHR0aGlzLnN0YXJ0KCk7XG5cdFx0XHRyZXR1cm4gMDtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ydW5uaW5nICkge1xuXG5cdFx0XHR2YXIgbmV3VGltZSA9ICggdHlwZW9mIHBlcmZvcm1hbmNlID09PSAndW5kZWZpbmVkJyA/IERhdGUgOiBwZXJmb3JtYW5jZSApLm5vdygpO1xuXG5cdFx0XHRkaWZmID0gKCBuZXdUaW1lIC0gdGhpcy5vbGRUaW1lICkgLyAxMDAwO1xuXHRcdFx0dGhpcy5vbGRUaW1lID0gbmV3VGltZTtcblxuXHRcdFx0dGhpcy5lbGFwc2VkVGltZSArPSBkaWZmO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRpZmY7XG5cblx0fVxuXG59ICk7XG5cbi8qKlxuICogQGF1dGhvciBiaG91c3RvbiAvIGh0dHA6Ly9jbGFyYS5pb1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKlxuICogUmVmOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TcGhlcmljYWxfY29vcmRpbmF0ZV9zeXN0ZW1cbiAqXG4gKiBUaGUgcG9sZXMgKHBoaSkgYXJlIGF0IHRoZSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgeSBheGlzLlxuICogVGhlIGVxdWF0b3Igc3RhcnRzIGF0IHBvc2l0aXZlIHouXG4gKi9cblxuZnVuY3Rpb24gU3BoZXJpY2FsKCByYWRpdXMsIHBoaSwgdGhldGEgKSB7XG5cblx0dGhpcy5yYWRpdXMgPSAoIHJhZGl1cyAhPT0gdW5kZWZpbmVkICkgPyByYWRpdXMgOiAxLjA7XG5cdHRoaXMucGhpID0gKCBwaGkgIT09IHVuZGVmaW5lZCApID8gcGhpIDogMDsgLy8gdXAgLyBkb3duIHRvd2FyZHMgdG9wIGFuZCBib3R0b20gcG9sZVxuXHR0aGlzLnRoZXRhID0gKCB0aGV0YSAhPT0gdW5kZWZpbmVkICkgPyB0aGV0YSA6IDA7IC8vIGFyb3VuZCB0aGUgZXF1YXRvciBvZiB0aGUgc3BoZXJlXG5cblx0cmV0dXJuIHRoaXM7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggU3BoZXJpY2FsLnByb3RvdHlwZSwge1xuXG5cdHNldDogZnVuY3Rpb24gKCByYWRpdXMsIHBoaSwgdGhldGEgKSB7XG5cblx0XHR0aGlzLnJhZGl1cyA9IHJhZGl1cztcblx0XHR0aGlzLnBoaSA9IHBoaTtcblx0XHR0aGlzLnRoZXRhID0gdGhldGE7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KCB0aGlzICk7XG5cblx0fSxcblxuXHRjb3B5OiBmdW5jdGlvbiAoIG90aGVyICkge1xuXG5cdFx0dGhpcy5yYWRpdXMgPSBvdGhlci5yYWRpdXM7XG5cdFx0dGhpcy5waGkgPSBvdGhlci5waGk7XG5cdFx0dGhpcy50aGV0YSA9IG90aGVyLnRoZXRhO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHQvLyByZXN0cmljdCBwaGkgdG8gYmUgYmV0d2VlIEVQUyBhbmQgUEktRVBTXG5cdG1ha2VTYWZlOiBmdW5jdGlvbigpIHtcblxuXHRcdHZhciBFUFMgPSAwLjAwMDAwMTtcblx0XHR0aGlzLnBoaSA9IE1hdGgubWF4KCBFUFMsIE1hdGgubWluKCBNYXRoLlBJIC0gRVBTLCB0aGlzLnBoaSApICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHNldEZyb21WZWN0b3IzOiBmdW5jdGlvbiggdmVjMyApIHtcblxuXHRcdHRoaXMucmFkaXVzID0gdmVjMy5sZW5ndGgoKTtcblxuXHRcdGlmICggdGhpcy5yYWRpdXMgPT09IDAgKSB7XG5cblx0XHRcdHRoaXMudGhldGEgPSAwO1xuXHRcdFx0dGhpcy5waGkgPSAwO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dGhpcy50aGV0YSA9IE1hdGguYXRhbjIoIHZlYzMueCwgdmVjMy56ICk7IC8vIGVxdWF0b3IgYW5nbGUgYXJvdW5kIHktdXAgYXhpc1xuXHRcdFx0dGhpcy5waGkgPSBNYXRoLmFjb3MoIF9NYXRoLmNsYW1wKCB2ZWMzLnkgLyB0aGlzLnJhZGl1cywgLSAxLCAxICkgKTsgLy8gcG9sYXIgYW5nbGVcblxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKlxuICogUmVmOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DeWxpbmRyaWNhbF9jb29yZGluYXRlX3N5c3RlbVxuICpcbiAqL1xuXG5mdW5jdGlvbiBDeWxpbmRyaWNhbCggcmFkaXVzLCB0aGV0YSwgeSApIHtcblxuXHR0aGlzLnJhZGl1cyA9ICggcmFkaXVzICE9PSB1bmRlZmluZWQgKSA/IHJhZGl1cyA6IDEuMDsgLy8gZGlzdGFuY2UgZnJvbSB0aGUgb3JpZ2luIHRvIGEgcG9pbnQgaW4gdGhlIHgteiBwbGFuZVxuXHR0aGlzLnRoZXRhID0gKCB0aGV0YSAhPT0gdW5kZWZpbmVkICkgPyB0aGV0YSA6IDA7IC8vIGNvdW50ZXJjbG9ja3dpc2UgYW5nbGUgaW4gdGhlIHgteiBwbGFuZSBtZWFzdXJlZCBpbiByYWRpYW5zIGZyb20gdGhlIHBvc2l0aXZlIHotYXhpc1xuXHR0aGlzLnkgPSAoIHkgIT09IHVuZGVmaW5lZCApID8geSA6IDA7IC8vIGhlaWdodCBhYm92ZSB0aGUgeC16IHBsYW5lXG5cblx0cmV0dXJuIHRoaXM7XG5cbn1cblxuT2JqZWN0LmFzc2lnbiggQ3lsaW5kcmljYWwucHJvdG90eXBlLCB7XG5cblx0c2V0OiBmdW5jdGlvbiAoIHJhZGl1cywgdGhldGEsIHkgKSB7XG5cblx0XHR0aGlzLnJhZGl1cyA9IHJhZGl1cztcblx0XHR0aGlzLnRoZXRhID0gdGhldGE7XG5cdFx0dGhpcy55ID0geTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcigpLmNvcHkoIHRoaXMgKTtcblxuXHR9LFxuXG5cdGNvcHk6IGZ1bmN0aW9uICggb3RoZXIgKSB7XG5cblx0XHR0aGlzLnJhZGl1cyA9IG90aGVyLnJhZGl1cztcblx0XHR0aGlzLnRoZXRhID0gb3RoZXIudGhldGE7XG5cdFx0dGhpcy55ID0gb3RoZXIueTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH0sXG5cblx0c2V0RnJvbVZlY3RvcjM6IGZ1bmN0aW9uKCB2ZWMzICkge1xuXG5cdFx0dGhpcy5yYWRpdXMgPSBNYXRoLnNxcnQoIHZlYzMueCAqIHZlYzMueCArIHZlYzMueiAqIHZlYzMueiApO1xuXHRcdHRoaXMudGhldGEgPSBNYXRoLmF0YW4yKCB2ZWMzLngsIHZlYzMueiApO1xuXHRcdHRoaXMueSA9IHZlYzMueTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH1cblxufSApO1xuXG4vKipcclxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cclxuICovXHJcblxyXG5mdW5jdGlvbiBNb3JwaEJsZW5kTWVzaCggZ2VvbWV0cnksIG1hdGVyaWFsICkge1xuXHJcblx0TWVzaC5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcclxuXHJcblx0dGhpcy5hbmltYXRpb25zTWFwID0ge307XHJcblx0dGhpcy5hbmltYXRpb25zTGlzdCA9IFtdO1xyXG5cclxuXHQvLyBwcmVwYXJlIGRlZmF1bHQgYW5pbWF0aW9uXHJcblx0Ly8gKGFsbCBmcmFtZXMgcGxheWVkIHRvZ2V0aGVyIGluIDEgc2Vjb25kKVxyXG5cclxuXHR2YXIgbnVtRnJhbWVzID0gdGhpcy5nZW9tZXRyeS5tb3JwaFRhcmdldHMubGVuZ3RoO1xyXG5cclxuXHR2YXIgbmFtZSA9IFwiX19kZWZhdWx0XCI7XHJcblxyXG5cdHZhciBzdGFydEZyYW1lID0gMDtcclxuXHR2YXIgZW5kRnJhbWUgPSBudW1GcmFtZXMgLSAxO1xyXG5cclxuXHR2YXIgZnBzID0gbnVtRnJhbWVzIC8gMTtcclxuXHJcblx0dGhpcy5jcmVhdGVBbmltYXRpb24oIG5hbWUsIHN0YXJ0RnJhbWUsIGVuZEZyYW1lLCBmcHMgKTtcclxuXHR0aGlzLnNldEFuaW1hdGlvbldlaWdodCggbmFtZSwgMSApO1xyXG5cclxufVxyXG5cclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTWVzaC5wcm90b3R5cGUgKTtcclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTW9ycGhCbGVuZE1lc2g7XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuY3JlYXRlQW5pbWF0aW9uID0gZnVuY3Rpb24gKCBuYW1lLCBzdGFydCwgZW5kLCBmcHMgKSB7XHJcblxyXG5cdHZhciBhbmltYXRpb24gPSB7XHJcblxyXG5cdFx0c3RhcnQ6IHN0YXJ0LFxyXG5cdFx0ZW5kOiBlbmQsXHJcblxyXG5cdFx0bGVuZ3RoOiBlbmQgLSBzdGFydCArIDEsXHJcblxyXG5cdFx0ZnBzOiBmcHMsXHJcblx0XHRkdXJhdGlvbjogKCBlbmQgLSBzdGFydCApIC8gZnBzLFxyXG5cclxuXHRcdGxhc3RGcmFtZTogMCxcclxuXHRcdGN1cnJlbnRGcmFtZTogMCxcclxuXHJcblx0XHRhY3RpdmU6IGZhbHNlLFxyXG5cclxuXHRcdHRpbWU6IDAsXHJcblx0XHRkaXJlY3Rpb246IDEsXHJcblx0XHR3ZWlnaHQ6IDEsXHJcblxyXG5cdFx0ZGlyZWN0aW9uQmFja3dhcmRzOiBmYWxzZSxcclxuXHRcdG1pcnJvcmVkTG9vcDogZmFsc2VcclxuXHJcblx0fTtcclxuXHJcblx0dGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF0gPSBhbmltYXRpb247XHJcblx0dGhpcy5hbmltYXRpb25zTGlzdC5wdXNoKCBhbmltYXRpb24gKTtcclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuYXV0b0NyZWF0ZUFuaW1hdGlvbnMgPSBmdW5jdGlvbiAoIGZwcyApIHtcclxuXHJcblx0dmFyIHBhdHRlcm4gPSAvKFthLXpdKylfPyhcXGQrKS9pO1xyXG5cclxuXHR2YXIgZmlyc3RBbmltYXRpb24sIGZyYW1lUmFuZ2VzID0ge307XHJcblxyXG5cdHZhciBnZW9tZXRyeSA9IHRoaXMuZ2VvbWV0cnk7XHJcblxyXG5cdGZvciAoIHZhciBpID0gMCwgaWwgPSBnZW9tZXRyeS5tb3JwaFRhcmdldHMubGVuZ3RoOyBpIDwgaWw7IGkgKysgKSB7XHJcblxyXG5cdFx0dmFyIG1vcnBoID0gZ2VvbWV0cnkubW9ycGhUYXJnZXRzWyBpIF07XHJcblx0XHR2YXIgY2h1bmtzID0gbW9ycGgubmFtZS5tYXRjaCggcGF0dGVybiApO1xyXG5cclxuXHRcdGlmICggY2h1bmtzICYmIGNodW5rcy5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0dmFyIG5hbWUgPSBjaHVua3NbIDEgXTtcclxuXHJcblx0XHRcdGlmICggISBmcmFtZVJhbmdlc1sgbmFtZSBdICkgZnJhbWVSYW5nZXNbIG5hbWUgXSA9IHsgc3RhcnQ6IEluZmluaXR5LCBlbmQ6IC0gSW5maW5pdHkgfTtcclxuXHJcblx0XHRcdHZhciByYW5nZSA9IGZyYW1lUmFuZ2VzWyBuYW1lIF07XHJcblxyXG5cdFx0XHRpZiAoIGkgPCByYW5nZS5zdGFydCApIHJhbmdlLnN0YXJ0ID0gaTtcclxuXHRcdFx0aWYgKCBpID4gcmFuZ2UuZW5kICkgcmFuZ2UuZW5kID0gaTtcclxuXHJcblx0XHRcdGlmICggISBmaXJzdEFuaW1hdGlvbiApIGZpcnN0QW5pbWF0aW9uID0gbmFtZTtcclxuXHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0Zm9yICggdmFyIG5hbWUgaW4gZnJhbWVSYW5nZXMgKSB7XHJcblxyXG5cdFx0dmFyIHJhbmdlID0gZnJhbWVSYW5nZXNbIG5hbWUgXTtcclxuXHRcdHRoaXMuY3JlYXRlQW5pbWF0aW9uKCBuYW1lLCByYW5nZS5zdGFydCwgcmFuZ2UuZW5kLCBmcHMgKTtcclxuXHJcblx0fVxyXG5cclxuXHR0aGlzLmZpcnN0QW5pbWF0aW9uID0gZmlyc3RBbmltYXRpb247XHJcblxyXG59O1xyXG5cclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlLnNldEFuaW1hdGlvbkRpcmVjdGlvbkZvcndhcmQgPSBmdW5jdGlvbiAoIG5hbWUgKSB7XHJcblxyXG5cdHZhciBhbmltYXRpb24gPSB0aGlzLmFuaW1hdGlvbnNNYXBbIG5hbWUgXTtcclxuXHJcblx0aWYgKCBhbmltYXRpb24gKSB7XHJcblxyXG5cdFx0YW5pbWF0aW9uLmRpcmVjdGlvbiA9IDE7XHJcblx0XHRhbmltYXRpb24uZGlyZWN0aW9uQmFja3dhcmRzID0gZmFsc2U7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuc2V0QW5pbWF0aW9uRGlyZWN0aW9uQmFja3dhcmQgPSBmdW5jdGlvbiAoIG5hbWUgKSB7XHJcblxyXG5cdHZhciBhbmltYXRpb24gPSB0aGlzLmFuaW1hdGlvbnNNYXBbIG5hbWUgXTtcclxuXHJcblx0aWYgKCBhbmltYXRpb24gKSB7XHJcblxyXG5cdFx0YW5pbWF0aW9uLmRpcmVjdGlvbiA9IC0gMTtcclxuXHRcdGFuaW1hdGlvbi5kaXJlY3Rpb25CYWNrd2FyZHMgPSB0cnVlO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5cclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlLnNldEFuaW1hdGlvbkZQUyA9IGZ1bmN0aW9uICggbmFtZSwgZnBzICkge1xyXG5cclxuXHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF07XHJcblxyXG5cdGlmICggYW5pbWF0aW9uICkge1xyXG5cclxuXHRcdGFuaW1hdGlvbi5mcHMgPSBmcHM7XHJcblx0XHRhbmltYXRpb24uZHVyYXRpb24gPSAoIGFuaW1hdGlvbi5lbmQgLSBhbmltYXRpb24uc3RhcnQgKSAvIGFuaW1hdGlvbi5mcHM7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuc2V0QW5pbWF0aW9uRHVyYXRpb24gPSBmdW5jdGlvbiAoIG5hbWUsIGR1cmF0aW9uICkge1xyXG5cclxuXHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF07XHJcblxyXG5cdGlmICggYW5pbWF0aW9uICkge1xyXG5cclxuXHRcdGFuaW1hdGlvbi5kdXJhdGlvbiA9IGR1cmF0aW9uO1xyXG5cdFx0YW5pbWF0aW9uLmZwcyA9ICggYW5pbWF0aW9uLmVuZCAtIGFuaW1hdGlvbi5zdGFydCApIC8gYW5pbWF0aW9uLmR1cmF0aW9uO1xyXG5cclxuXHR9XHJcblxyXG59O1xyXG5cclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlLnNldEFuaW1hdGlvbldlaWdodCA9IGZ1bmN0aW9uICggbmFtZSwgd2VpZ2h0ICkge1xyXG5cclxuXHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF07XHJcblxyXG5cdGlmICggYW5pbWF0aW9uICkge1xyXG5cclxuXHRcdGFuaW1hdGlvbi53ZWlnaHQgPSB3ZWlnaHQ7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuc2V0QW5pbWF0aW9uVGltZSA9IGZ1bmN0aW9uICggbmFtZSwgdGltZSApIHtcclxuXHJcblx0dmFyIGFuaW1hdGlvbiA9IHRoaXMuYW5pbWF0aW9uc01hcFsgbmFtZSBdO1xyXG5cclxuXHRpZiAoIGFuaW1hdGlvbiApIHtcclxuXHJcblx0XHRhbmltYXRpb24udGltZSA9IHRpbWU7XHJcblxyXG5cdH1cclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuZ2V0QW5pbWF0aW9uVGltZSA9IGZ1bmN0aW9uICggbmFtZSApIHtcclxuXHJcblx0dmFyIHRpbWUgPSAwO1xyXG5cclxuXHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF07XHJcblxyXG5cdGlmICggYW5pbWF0aW9uICkge1xyXG5cclxuXHRcdHRpbWUgPSBhbmltYXRpb24udGltZTtcclxuXHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGltZTtcclxuXHJcbn07XHJcblxyXG5Nb3JwaEJsZW5kTWVzaC5wcm90b3R5cGUuZ2V0QW5pbWF0aW9uRHVyYXRpb24gPSBmdW5jdGlvbiAoIG5hbWUgKSB7XHJcblxyXG5cdHZhciBkdXJhdGlvbiA9IC0gMTtcclxuXHJcblx0dmFyIGFuaW1hdGlvbiA9IHRoaXMuYW5pbWF0aW9uc01hcFsgbmFtZSBdO1xyXG5cclxuXHRpZiAoIGFuaW1hdGlvbiApIHtcclxuXHJcblx0XHRkdXJhdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbjtcclxuXHJcblx0fVxyXG5cclxuXHRyZXR1cm4gZHVyYXRpb247XHJcblxyXG59O1xyXG5cclxuTW9ycGhCbGVuZE1lc2gucHJvdG90eXBlLnBsYXlBbmltYXRpb24gPSBmdW5jdGlvbiAoIG5hbWUgKSB7XHJcblxyXG5cdHZhciBhbmltYXRpb24gPSB0aGlzLmFuaW1hdGlvbnNNYXBbIG5hbWUgXTtcclxuXHJcblx0aWYgKCBhbmltYXRpb24gKSB7XHJcblxyXG5cdFx0YW5pbWF0aW9uLnRpbWUgPSAwO1xyXG5cdFx0YW5pbWF0aW9uLmFjdGl2ZSA9IHRydWU7XHJcblxyXG5cdH0gZWxzZSB7XHJcblxyXG5cdFx0Y29uc29sZS53YXJuKCBcIlRIUkVFLk1vcnBoQmxlbmRNZXNoOiBhbmltYXRpb25bXCIgKyBuYW1lICsgXCJdIHVuZGVmaW5lZCBpbiAucGxheUFuaW1hdGlvbigpXCIgKTtcclxuXHJcblx0fVxyXG5cclxufTtcclxuXHJcbk1vcnBoQmxlbmRNZXNoLnByb3RvdHlwZS5zdG9wQW5pbWF0aW9uID0gZnVuY3Rpb24gKCBuYW1lICkge1xyXG5cclxuXHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTWFwWyBuYW1lIF07XHJcblxyXG5cdGlmICggYW5pbWF0aW9uICkge1xyXG5cclxuXHRcdGFuaW1hdGlvbi5hY3RpdmUgPSBmYWxzZTtcclxuXHJcblx0fVxyXG5cclxufTtcclxuXHJcbk1vcnBoQmxlbmRNZXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoIGRlbHRhICkge1xyXG5cclxuXHRmb3IgKCB2YXIgaSA9IDAsIGlsID0gdGhpcy5hbmltYXRpb25zTGlzdC5sZW5ndGg7IGkgPCBpbDsgaSArKyApIHtcclxuXHJcblx0XHR2YXIgYW5pbWF0aW9uID0gdGhpcy5hbmltYXRpb25zTGlzdFsgaSBdO1xyXG5cclxuXHRcdGlmICggISBhbmltYXRpb24uYWN0aXZlICkgY29udGludWU7XHJcblxyXG5cdFx0dmFyIGZyYW1lVGltZSA9IGFuaW1hdGlvbi5kdXJhdGlvbiAvIGFuaW1hdGlvbi5sZW5ndGg7XHJcblxyXG5cdFx0YW5pbWF0aW9uLnRpbWUgKz0gYW5pbWF0aW9uLmRpcmVjdGlvbiAqIGRlbHRhO1xyXG5cclxuXHRcdGlmICggYW5pbWF0aW9uLm1pcnJvcmVkTG9vcCApIHtcclxuXHJcblx0XHRcdGlmICggYW5pbWF0aW9uLnRpbWUgPiBhbmltYXRpb24uZHVyYXRpb24gfHwgYW5pbWF0aW9uLnRpbWUgPCAwICkge1xyXG5cclxuXHRcdFx0XHRhbmltYXRpb24uZGlyZWN0aW9uICo9IC0gMTtcclxuXHJcblx0XHRcdFx0aWYgKCBhbmltYXRpb24udGltZSA+IGFuaW1hdGlvbi5kdXJhdGlvbiApIHtcclxuXHJcblx0XHRcdFx0XHRhbmltYXRpb24udGltZSA9IGFuaW1hdGlvbi5kdXJhdGlvbjtcclxuXHRcdFx0XHRcdGFuaW1hdGlvbi5kaXJlY3Rpb25CYWNrd2FyZHMgPSB0cnVlO1xyXG5cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmICggYW5pbWF0aW9uLnRpbWUgPCAwICkge1xyXG5cclxuXHRcdFx0XHRcdGFuaW1hdGlvbi50aW1lID0gMDtcclxuXHRcdFx0XHRcdGFuaW1hdGlvbi5kaXJlY3Rpb25CYWNrd2FyZHMgPSBmYWxzZTtcclxuXHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0fVxyXG5cclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRhbmltYXRpb24udGltZSA9IGFuaW1hdGlvbi50aW1lICUgYW5pbWF0aW9uLmR1cmF0aW9uO1xyXG5cclxuXHRcdFx0aWYgKCBhbmltYXRpb24udGltZSA8IDAgKSBhbmltYXRpb24udGltZSArPSBhbmltYXRpb24uZHVyYXRpb247XHJcblxyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBrZXlmcmFtZSA9IGFuaW1hdGlvbi5zdGFydCArIF9NYXRoLmNsYW1wKCBNYXRoLmZsb29yKCBhbmltYXRpb24udGltZSAvIGZyYW1lVGltZSApLCAwLCBhbmltYXRpb24ubGVuZ3RoIC0gMSApO1xyXG5cdFx0dmFyIHdlaWdodCA9IGFuaW1hdGlvbi53ZWlnaHQ7XHJcblxyXG5cdFx0aWYgKCBrZXlmcmFtZSAhPT0gYW5pbWF0aW9uLmN1cnJlbnRGcmFtZSApIHtcclxuXHJcblx0XHRcdHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBhbmltYXRpb24ubGFzdEZyYW1lIF0gPSAwO1xyXG5cdFx0XHR0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgYW5pbWF0aW9uLmN1cnJlbnRGcmFtZSBdID0gMSAqIHdlaWdodDtcclxuXHJcblx0XHRcdHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBrZXlmcmFtZSBdID0gMDtcclxuXHJcblx0XHRcdGFuaW1hdGlvbi5sYXN0RnJhbWUgPSBhbmltYXRpb24uY3VycmVudEZyYW1lO1xyXG5cdFx0XHRhbmltYXRpb24uY3VycmVudEZyYW1lID0ga2V5ZnJhbWU7XHJcblxyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBtaXggPSAoIGFuaW1hdGlvbi50aW1lICUgZnJhbWVUaW1lICkgLyBmcmFtZVRpbWU7XHJcblxyXG5cdFx0aWYgKCBhbmltYXRpb24uZGlyZWN0aW9uQmFja3dhcmRzICkgbWl4ID0gMSAtIG1peDtcclxuXHJcblx0XHRpZiAoIGFuaW1hdGlvbi5jdXJyZW50RnJhbWUgIT09IGFuaW1hdGlvbi5sYXN0RnJhbWUgKSB7XHJcblxyXG5cdFx0XHR0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgYW5pbWF0aW9uLmN1cnJlbnRGcmFtZSBdID0gbWl4ICogd2VpZ2h0O1xyXG5cdFx0XHR0aGlzLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgYW5pbWF0aW9uLmxhc3RGcmFtZSBdID0gKCAxIC0gbWl4ICkgKiB3ZWlnaHQ7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdHRoaXMubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBhbmltYXRpb24uY3VycmVudEZyYW1lIF0gPSB3ZWlnaHQ7XHJcblxyXG5cdFx0fVxyXG5cclxuXHR9XHJcblxyXG59O1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKi9cblxuZnVuY3Rpb24gSW1tZWRpYXRlUmVuZGVyT2JqZWN0KCBtYXRlcmlhbCApIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5tYXRlcmlhbCA9IG1hdGVyaWFsO1xuXHR0aGlzLnJlbmRlciA9IGZ1bmN0aW9uICggcmVuZGVyQ2FsbGJhY2sgKSB7fTtcblxufVxuXG5JbW1lZGlhdGVSZW5kZXJPYmplY3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICk7XG5JbW1lZGlhdGVSZW5kZXJPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gSW1tZWRpYXRlUmVuZGVyT2JqZWN0O1xuXG5JbW1lZGlhdGVSZW5kZXJPYmplY3QucHJvdG90eXBlLmlzSW1tZWRpYXRlUmVuZGVyT2JqZWN0ID0gdHJ1ZTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4qL1xuXG5mdW5jdGlvbiBWZXJ0ZXhOb3JtYWxzSGVscGVyKCBvYmplY3QsIHNpemUsIGhleCwgbGluZXdpZHRoICkge1xuXG5cdHRoaXMub2JqZWN0ID0gb2JqZWN0O1xuXG5cdHRoaXMuc2l6ZSA9ICggc2l6ZSAhPT0gdW5kZWZpbmVkICkgPyBzaXplIDogMTtcblxuXHR2YXIgY29sb3IgPSAoIGhleCAhPT0gdW5kZWZpbmVkICkgPyBoZXggOiAweGZmMDAwMDtcblxuXHR2YXIgd2lkdGggPSAoIGxpbmV3aWR0aCAhPT0gdW5kZWZpbmVkICkgPyBsaW5ld2lkdGggOiAxO1xuXG5cdC8vXG5cblx0dmFyIG5Ob3JtYWxzID0gMDtcblxuXHR2YXIgb2JqR2VvbWV0cnkgPSB0aGlzLm9iamVjdC5nZW9tZXRyeTtcblxuXHRpZiAoIG9iakdlb21ldHJ5ICYmIG9iakdlb21ldHJ5LmlzR2VvbWV0cnkgKSB7XG5cblx0XHRuTm9ybWFscyA9IG9iakdlb21ldHJ5LmZhY2VzLmxlbmd0aCAqIDM7XG5cblx0fSBlbHNlIGlmICggb2JqR2VvbWV0cnkgJiYgb2JqR2VvbWV0cnkuaXNCdWZmZXJHZW9tZXRyeSApIHtcblxuXHRcdG5Ob3JtYWxzID0gb2JqR2VvbWV0cnkuYXR0cmlidXRlcy5ub3JtYWwuY291bnQ7XG5cblx0fVxuXG5cdC8vXG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cblx0dmFyIHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBuTm9ybWFscyAqIDIgKiAzLCAzICk7XG5cblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBwb3NpdGlvbnMgKTtcblxuXHRMaW5lU2VnbWVudHMuY2FsbCggdGhpcywgZ2VvbWV0cnksIG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogY29sb3IsIGxpbmV3aWR0aDogd2lkdGggfSApICk7XG5cblx0Ly9cblxuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLnVwZGF0ZSgpO1xuXG59XG5cblZlcnRleE5vcm1hbHNIZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTGluZVNlZ21lbnRzLnByb3RvdHlwZSApO1xuVmVydGV4Tm9ybWFsc0hlbHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBWZXJ0ZXhOb3JtYWxzSGVscGVyO1xuXG5WZXJ0ZXhOb3JtYWxzSGVscGVyLnByb3RvdHlwZS51cGRhdGUgPSAoIGZ1bmN0aW9uICgpIHtcblxuXHR2YXIgdjEgPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgdjIgPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgbm9ybWFsTWF0cml4ID0gbmV3IE1hdHJpeDMoKTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCkge1xuXG5cdFx0dmFyIGtleXMgPSBbICdhJywgJ2InLCAnYycgXTtcblxuXHRcdHRoaXMub2JqZWN0LnVwZGF0ZU1hdHJpeFdvcmxkKCB0cnVlICk7XG5cblx0XHRub3JtYWxNYXRyaXguZ2V0Tm9ybWFsTWF0cml4KCB0aGlzLm9iamVjdC5tYXRyaXhXb3JsZCApO1xuXG5cdFx0dmFyIG1hdHJpeFdvcmxkID0gdGhpcy5vYmplY3QubWF0cml4V29ybGQ7XG5cblx0XHR2YXIgcG9zaXRpb24gPSB0aGlzLmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cblx0XHQvL1xuXG5cdFx0dmFyIG9iakdlb21ldHJ5ID0gdGhpcy5vYmplY3QuZ2VvbWV0cnk7XG5cblx0XHRpZiAoIG9iakdlb21ldHJ5ICYmIG9iakdlb21ldHJ5LmlzR2VvbWV0cnkgKSB7XG5cblx0XHRcdHZhciB2ZXJ0aWNlcyA9IG9iakdlb21ldHJ5LnZlcnRpY2VzO1xuXG5cdFx0XHR2YXIgZmFjZXMgPSBvYmpHZW9tZXRyeS5mYWNlcztcblxuXHRcdFx0dmFyIGlkeCA9IDA7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbCA9IGZhY2VzLmxlbmd0aDsgaSA8IGw7IGkgKysgKSB7XG5cblx0XHRcdFx0dmFyIGZhY2UgPSBmYWNlc1sgaSBdO1xuXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMCwgamwgPSBmYWNlLnZlcnRleE5vcm1hbHMubGVuZ3RoOyBqIDwgamw7IGogKysgKSB7XG5cblx0XHRcdFx0XHR2YXIgdmVydGV4ID0gdmVydGljZXNbIGZhY2VbIGtleXNbIGogXSBdIF07XG5cblx0XHRcdFx0XHR2YXIgbm9ybWFsID0gZmFjZS52ZXJ0ZXhOb3JtYWxzWyBqIF07XG5cblx0XHRcdFx0XHR2MS5jb3B5KCB2ZXJ0ZXggKS5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0XHR2Mi5jb3B5KCBub3JtYWwgKS5hcHBseU1hdHJpeDMoIG5vcm1hbE1hdHJpeCApLm5vcm1hbGl6ZSgpLm11bHRpcGx5U2NhbGFyKCB0aGlzLnNpemUgKS5hZGQoIHYxICk7XG5cblx0XHRcdFx0XHRwb3NpdGlvbi5zZXRYWVooIGlkeCwgdjEueCwgdjEueSwgdjEueiApO1xuXG5cdFx0XHRcdFx0aWR4ID0gaWR4ICsgMTtcblxuXHRcdFx0XHRcdHBvc2l0aW9uLnNldFhZWiggaWR4LCB2Mi54LCB2Mi55LCB2Mi56ICk7XG5cblx0XHRcdFx0XHRpZHggPSBpZHggKyAxO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggb2JqR2VvbWV0cnkgJiYgb2JqR2VvbWV0cnkuaXNCdWZmZXJHZW9tZXRyeSApIHtcblxuXHRcdFx0dmFyIG9ialBvcyA9IG9iakdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cblx0XHRcdHZhciBvYmpOb3JtID0gb2JqR2VvbWV0cnkuYXR0cmlidXRlcy5ub3JtYWw7XG5cblx0XHRcdHZhciBpZHggPSAwO1xuXG5cdFx0XHQvLyBmb3Igc2ltcGxpY2l0eSwgaWdub3JlIGluZGV4IGFuZCBkcmF3Y2FsbHMsIGFuZCByZW5kZXIgZXZlcnkgbm9ybWFsXG5cblx0XHRcdGZvciAoIHZhciBqID0gMCwgamwgPSBvYmpQb3MuY291bnQ7IGogPCBqbDsgaiArKyApIHtcblxuXHRcdFx0XHR2MS5zZXQoIG9ialBvcy5nZXRYKCBqICksIG9ialBvcy5nZXRZKCBqICksIG9ialBvcy5nZXRaKCBqICkgKS5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cblx0XHRcdFx0djIuc2V0KCBvYmpOb3JtLmdldFgoIGogKSwgb2JqTm9ybS5nZXRZKCBqICksIG9iak5vcm0uZ2V0WiggaiApICk7XG5cblx0XHRcdFx0djIuYXBwbHlNYXRyaXgzKCBub3JtYWxNYXRyaXggKS5ub3JtYWxpemUoKS5tdWx0aXBseVNjYWxhciggdGhpcy5zaXplICkuYWRkKCB2MSApO1xuXG5cdFx0XHRcdHBvc2l0aW9uLnNldFhZWiggaWR4LCB2MS54LCB2MS55LCB2MS56ICk7XG5cblx0XHRcdFx0aWR4ID0gaWR4ICsgMTtcblxuXHRcdFx0XHRwb3NpdGlvbi5zZXRYWVooIGlkeCwgdjIueCwgdjIueSwgdjIueiApO1xuXG5cdFx0XHRcdGlkeCA9IGlkeCArIDE7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHBvc2l0aW9uLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHR9O1xuXG59KCkgKTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuKi9cblxuZnVuY3Rpb24gU3BvdExpZ2h0SGVscGVyKCBsaWdodCApIHtcblxuXHRPYmplY3QzRC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5saWdodCA9IGxpZ2h0O1xuXHR0aGlzLmxpZ2h0LnVwZGF0ZU1hdHJpeFdvcmxkKCk7XG5cblx0dGhpcy5tYXRyaXggPSBsaWdodC5tYXRyaXhXb3JsZDtcblx0dGhpcy5tYXRyaXhBdXRvVXBkYXRlID0gZmFsc2U7XG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cblx0dmFyIHBvc2l0aW9ucyA9IFtcblx0XHQwLCAwLCAwLCAgIDAsICAgMCwgICAxLFxuXHRcdDAsIDAsIDAsICAgMSwgICAwLCAgIDEsXG5cdFx0MCwgMCwgMCwgLSAxLCAgIDAsICAgMSxcblx0XHQwLCAwLCAwLCAgIDAsICAgMSwgICAxLFxuXHRcdDAsIDAsIDAsICAgMCwgLSAxLCAgIDFcblx0XTtcblxuXHRmb3IgKCB2YXIgaSA9IDAsIGogPSAxLCBsID0gMzI7IGkgPCBsOyBpICsrLCBqICsrICkge1xuXG5cdFx0dmFyIHAxID0gKCBpIC8gbCApICogTWF0aC5QSSAqIDI7XG5cdFx0dmFyIHAyID0gKCBqIC8gbCApICogTWF0aC5QSSAqIDI7XG5cblx0XHRwb3NpdGlvbnMucHVzaChcblx0XHRcdE1hdGguY29zKCBwMSApLCBNYXRoLnNpbiggcDEgKSwgMSxcblx0XHRcdE1hdGguY29zKCBwMiApLCBNYXRoLnNpbiggcDIgKSwgMVxuXHRcdCk7XG5cblx0fVxuXG5cdGdlb21ldHJ5LmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHBvc2l0aW9ucywgMyApICk7XG5cblx0dmFyIG1hdGVyaWFsID0gbmV3IExpbmVCYXNpY01hdGVyaWFsKCB7IGZvZzogZmFsc2UgfSApO1xuXG5cdHRoaXMuY29uZSA9IG5ldyBMaW5lU2VnbWVudHMoIGdlb21ldHJ5LCBtYXRlcmlhbCApO1xuXHR0aGlzLmFkZCggdGhpcy5jb25lICk7XG5cblx0dGhpcy51cGRhdGUoKTtcblxufVxuXG5TcG90TGlnaHRIZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggT2JqZWN0M0QucHJvdG90eXBlICk7XG5TcG90TGlnaHRIZWxwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU3BvdExpZ2h0SGVscGVyO1xuXG5TcG90TGlnaHRIZWxwZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cblx0dGhpcy5jb25lLmdlb21ldHJ5LmRpc3Bvc2UoKTtcblx0dGhpcy5jb25lLm1hdGVyaWFsLmRpc3Bvc2UoKTtcblxufTtcblxuU3BvdExpZ2h0SGVscGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIHZlY3RvciA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciB2ZWN0b3IyID0gbmV3IFZlY3RvcjMoKTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCkge1xuXG5cdFx0dmFyIGNvbmVMZW5ndGggPSB0aGlzLmxpZ2h0LmRpc3RhbmNlID8gdGhpcy5saWdodC5kaXN0YW5jZSA6IDEwMDA7XG5cdFx0dmFyIGNvbmVXaWR0aCA9IGNvbmVMZW5ndGggKiBNYXRoLnRhbiggdGhpcy5saWdodC5hbmdsZSApO1xuXG5cdFx0dGhpcy5jb25lLnNjYWxlLnNldCggY29uZVdpZHRoLCBjb25lV2lkdGgsIGNvbmVMZW5ndGggKTtcblxuXHRcdHZlY3Rvci5zZXRGcm9tTWF0cml4UG9zaXRpb24oIHRoaXMubGlnaHQubWF0cml4V29ybGQgKTtcblx0XHR2ZWN0b3IyLnNldEZyb21NYXRyaXhQb3NpdGlvbiggdGhpcy5saWdodC50YXJnZXQubWF0cml4V29ybGQgKTtcblxuXHRcdHRoaXMuY29uZS5sb29rQXQoIHZlY3RvcjIuc3ViKCB2ZWN0b3IgKSApO1xuXG5cdFx0dGhpcy5jb25lLm1hdGVyaWFsLmNvbG9yLmNvcHkoIHRoaXMubGlnaHQuY29sb3IgKTtcblxuXHR9O1xuXG59KCk7XG5cbi8qKlxuICogQGF1dGhvciBTZWFuIEdyaWZmaW4gLyBodHRwOi8vdHdpdHRlci5jb20vc2dyaWZcbiAqIEBhdXRob3IgTWljaGFlbCBHdWVycmVybyAvIGh0dHA6Ly9yZWFsaXR5bWVsdGRvd24uY29tXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBpa2VyciAvIGh0dHA6Ly92ZXJvbGQuY29tXG4gKiBAYXV0aG9yIE11Z2VuODcgLyBodHRwczovL2dpdGh1Yi5jb20vTXVnZW44N1xuICovXG5cbmZ1bmN0aW9uIFNrZWxldG9uSGVscGVyKCBvYmplY3QgKSB7XG5cblx0dGhpcy5ib25lcyA9IHRoaXMuZ2V0Qm9uZUxpc3QoIG9iamVjdCApO1xuXG5cdHZhciBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXG5cdHZhciB2ZXJ0aWNlcyA9IFtdO1xuXHR2YXIgY29sb3JzID0gW107XG5cblx0dmFyIGNvbG9yMSA9IG5ldyBDb2xvciggMCwgMCwgMSApO1xuXHR2YXIgY29sb3IyID0gbmV3IENvbG9yKCAwLCAxLCAwICk7XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5ib25lcy5sZW5ndGg7IGkgKysgKSB7XG5cblx0XHR2YXIgYm9uZSA9IHRoaXMuYm9uZXNbIGkgXTtcblxuXHRcdGlmICggYm9uZS5wYXJlbnQgJiYgYm9uZS5wYXJlbnQuaXNCb25lICkge1xuXG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCAwLCAwLCAwICk7XG5cdFx0XHR2ZXJ0aWNlcy5wdXNoKCAwLCAwLCAwICk7XG5cdFx0XHRjb2xvcnMucHVzaCggY29sb3IxLnIsIGNvbG9yMS5nLCBjb2xvcjEuYiApO1xuXHRcdFx0Y29sb3JzLnB1c2goIGNvbG9yMi5yLCBjb2xvcjIuZywgY29sb3IyLmIgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdjb2xvcicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBjb2xvcnMsIDMgKSApO1xuXG5cdHZhciBtYXRlcmlhbCA9IG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyB2ZXJ0ZXhDb2xvcnM6IFZlcnRleENvbG9ycywgZGVwdGhUZXN0OiBmYWxzZSwgZGVwdGhXcml0ZTogZmFsc2UsIHRyYW5zcGFyZW50OiB0cnVlIH0gKTtcblxuXHRMaW5lU2VnbWVudHMuY2FsbCggdGhpcywgZ2VvbWV0cnksIG1hdGVyaWFsICk7XG5cblx0dGhpcy5yb290ID0gb2JqZWN0O1xuXG5cdHRoaXMubWF0cml4ID0gb2JqZWN0Lm1hdHJpeFdvcmxkO1xuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLnVwZGF0ZSgpO1xuXG59XG5cblxuU2tlbGV0b25IZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTGluZVNlZ21lbnRzLnByb3RvdHlwZSApO1xuU2tlbGV0b25IZWxwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU2tlbGV0b25IZWxwZXI7XG5cblNrZWxldG9uSGVscGVyLnByb3RvdHlwZS5nZXRCb25lTGlzdCA9IGZ1bmN0aW9uKCBvYmplY3QgKSB7XG5cblx0dmFyIGJvbmVMaXN0ID0gW107XG5cblx0aWYgKCBvYmplY3QgJiYgb2JqZWN0LmlzQm9uZSApIHtcblxuXHRcdGJvbmVMaXN0LnB1c2goIG9iamVjdCApO1xuXG5cdH1cblxuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBvYmplY3QuY2hpbGRyZW4ubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0Ym9uZUxpc3QucHVzaC5hcHBseSggYm9uZUxpc3QsIHRoaXMuZ2V0Qm9uZUxpc3QoIG9iamVjdC5jaGlsZHJlblsgaSBdICkgKTtcblxuXHR9XG5cblx0cmV0dXJuIGJvbmVMaXN0O1xuXG59O1xuXG5Ta2VsZXRvbkhlbHBlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuXG5cdHZhciB2ZWN0b3IgPSBuZXcgVmVjdG9yMygpO1xuXG5cdHZhciBib25lTWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblx0dmFyIG1hdHJpeFdvcmxkSW52ID0gbmV3IE1hdHJpeDQoKTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCkge1xuXG5cdFx0dmFyIGdlb21ldHJ5ID0gdGhpcy5nZW9tZXRyeTtcblx0XHR2YXIgcG9zaXRpb24gPSBnZW9tZXRyeS5nZXRBdHRyaWJ1dGUoICdwb3NpdGlvbicgKTtcblxuXHRcdG1hdHJpeFdvcmxkSW52LmdldEludmVyc2UoIHRoaXMucm9vdC5tYXRyaXhXb3JsZCApO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBqID0gMDsgaSA8IHRoaXMuYm9uZXMubGVuZ3RoOyBpICsrICkge1xuXG5cdFx0XHR2YXIgYm9uZSA9IHRoaXMuYm9uZXNbIGkgXTtcblxuXHRcdFx0aWYgKCBib25lLnBhcmVudCAmJiBib25lLnBhcmVudC5pc0JvbmUgKSB7XG5cblx0XHRcdFx0Ym9uZU1hdHJpeC5tdWx0aXBseU1hdHJpY2VzKCBtYXRyaXhXb3JsZEludiwgYm9uZS5tYXRyaXhXb3JsZCApO1xuXHRcdFx0XHR2ZWN0b3Iuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCBib25lTWF0cml4ICk7XG5cdFx0XHRcdHBvc2l0aW9uLnNldFhZWiggaiwgdmVjdG9yLngsIHZlY3Rvci55LCB2ZWN0b3IueiApO1xuXG5cdFx0XHRcdGJvbmVNYXRyaXgubXVsdGlwbHlNYXRyaWNlcyggbWF0cml4V29ybGRJbnYsIGJvbmUucGFyZW50Lm1hdHJpeFdvcmxkICk7XG5cdFx0XHRcdHZlY3Rvci5zZXRGcm9tTWF0cml4UG9zaXRpb24oIGJvbmVNYXRyaXggKTtcblx0XHRcdFx0cG9zaXRpb24uc2V0WFlaKCBqICsgMSwgdmVjdG9yLngsIHZlY3Rvci55LCB2ZWN0b3IueiApO1xuXG5cdFx0XHRcdGogKz0gMjtcblxuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Z2VvbWV0cnkuZ2V0QXR0cmlidXRlKCAncG9zaXRpb24nICkubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdH07XG5cbn0oKTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqL1xuXG5mdW5jdGlvbiBQb2ludExpZ2h0SGVscGVyKCBsaWdodCwgc3BoZXJlU2l6ZSApIHtcblxuXHR0aGlzLmxpZ2h0ID0gbGlnaHQ7XG5cdHRoaXMubGlnaHQudXBkYXRlTWF0cml4V29ybGQoKTtcblxuXHR2YXIgZ2VvbWV0cnkgPSBuZXcgU3BoZXJlQnVmZmVyR2VvbWV0cnkoIHNwaGVyZVNpemUsIDQsIDIgKTtcblx0dmFyIG1hdGVyaWFsID0gbmV3IE1lc2hCYXNpY01hdGVyaWFsKCB7IHdpcmVmcmFtZTogdHJ1ZSwgZm9nOiBmYWxzZSB9ICk7XG5cdG1hdGVyaWFsLmNvbG9yLmNvcHkoIHRoaXMubGlnaHQuY29sb3IgKTtcblxuXHRNZXNoLmNhbGwoIHRoaXMsIGdlb21ldHJ5LCBtYXRlcmlhbCApO1xuXG5cdHRoaXMubWF0cml4ID0gdGhpcy5saWdodC5tYXRyaXhXb3JsZDtcblx0dGhpcy5tYXRyaXhBdXRvVXBkYXRlID0gZmFsc2U7XG5cblx0Lypcblx0dmFyIGRpc3RhbmNlR2VvbWV0cnkgPSBuZXcgVEhSRUUuSWNvc2FoZWRyb25HZW9tZXRyeSggMSwgMiApO1xuXHR2YXIgZGlzdGFuY2VNYXRlcmlhbCA9IG5ldyBUSFJFRS5NZXNoQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogaGV4Q29sb3IsIGZvZzogZmFsc2UsIHdpcmVmcmFtZTogdHJ1ZSwgb3BhY2l0eTogMC4xLCB0cmFuc3BhcmVudDogdHJ1ZSB9ICk7XG5cblx0dGhpcy5saWdodFNwaGVyZSA9IG5ldyBUSFJFRS5NZXNoKCBidWxiR2VvbWV0cnksIGJ1bGJNYXRlcmlhbCApO1xuXHR0aGlzLmxpZ2h0RGlzdGFuY2UgPSBuZXcgVEhSRUUuTWVzaCggZGlzdGFuY2VHZW9tZXRyeSwgZGlzdGFuY2VNYXRlcmlhbCApO1xuXG5cdHZhciBkID0gbGlnaHQuZGlzdGFuY2U7XG5cblx0aWYgKCBkID09PSAwLjAgKSB7XG5cblx0XHR0aGlzLmxpZ2h0RGlzdGFuY2UudmlzaWJsZSA9IGZhbHNlO1xuXG5cdH0gZWxzZSB7XG5cblx0XHR0aGlzLmxpZ2h0RGlzdGFuY2Uuc2NhbGUuc2V0KCBkLCBkLCBkICk7XG5cblx0fVxuXG5cdHRoaXMuYWRkKCB0aGlzLmxpZ2h0RGlzdGFuY2UgKTtcblx0Ki9cblxufVxuXG5Qb2ludExpZ2h0SGVscGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE1lc2gucHJvdG90eXBlICk7XG5Qb2ludExpZ2h0SGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBvaW50TGlnaHRIZWxwZXI7XG5cblBvaW50TGlnaHRIZWxwZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG5cblx0dGhpcy5nZW9tZXRyeS5kaXNwb3NlKCk7XG5cdHRoaXMubWF0ZXJpYWwuZGlzcG9zZSgpO1xuXG59O1xuXG5Qb2ludExpZ2h0SGVscGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG5cblx0dGhpcy5tYXRlcmlhbC5jb2xvci5jb3B5KCB0aGlzLmxpZ2h0LmNvbG9yICk7XG5cblx0Lypcblx0dmFyIGQgPSB0aGlzLmxpZ2h0LmRpc3RhbmNlO1xuXG5cdGlmICggZCA9PT0gMC4wICkge1xuXG5cdFx0dGhpcy5saWdodERpc3RhbmNlLnZpc2libGUgPSBmYWxzZTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0dGhpcy5saWdodERpc3RhbmNlLnZpc2libGUgPSB0cnVlO1xuXHRcdHRoaXMubGlnaHREaXN0YW5jZS5zY2FsZS5zZXQoIGQsIGQsIGQgKTtcblxuXHR9XG5cdCovXG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBhYmVsbmF0aW9uIC8gaHR0cDovL2dpdGh1Yi5jb20vYWJlbG5hdGlvblxuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cDovL2dpdGh1Yi5jb20vTXVnZW44N1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKi9cblxuZnVuY3Rpb24gUmVjdEFyZWFMaWdodEhlbHBlciggbGlnaHQgKSB7XG5cblx0T2JqZWN0M0QuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMubGlnaHQgPSBsaWdodDtcblx0dGhpcy5saWdodC51cGRhdGVNYXRyaXhXb3JsZCgpO1xuXG5cdHRoaXMubWF0cml4ID0gbGlnaHQubWF0cml4V29ybGQ7XG5cdHRoaXMubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXG5cdHZhciBtYXRlcmlhbCA9IG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogbGlnaHQuY29sb3IgfSApO1xuXG5cdHZhciBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXG5cdGdlb21ldHJ5LmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEJ1ZmZlckF0dHJpYnV0ZSggbmV3IEZsb2F0MzJBcnJheSggNSAqIDMgKSwgMyApICk7XG5cblx0dGhpcy5hZGQoIG5ldyBMaW5lKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSApO1xuXG5cdHRoaXMudXBkYXRlKCk7XG5cbn1cblxuUmVjdEFyZWFMaWdodEhlbHBlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBPYmplY3QzRC5wcm90b3R5cGUgKTtcblJlY3RBcmVhTGlnaHRIZWxwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUmVjdEFyZWFMaWdodEhlbHBlcjtcblxuUmVjdEFyZWFMaWdodEhlbHBlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcblxuXHR0aGlzLmNoaWxkcmVuWyAwIF0uZ2VvbWV0cnkuZGlzcG9zZSgpO1xuXHR0aGlzLmNoaWxkcmVuWyAwIF0ubWF0ZXJpYWwuZGlzcG9zZSgpO1xuXG59O1xuXG5SZWN0QXJlYUxpZ2h0SGVscGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIGxpbmUgPSB0aGlzLmNoaWxkcmVuWyAwIF07XG5cblx0Ly8gdXBkYXRlIG1hdGVyaWFsXG5cblx0bGluZS5tYXRlcmlhbC5jb2xvci5jb3B5KCB0aGlzLmxpZ2h0LmNvbG9yICk7XG5cblx0Ly8gY2FsY3VsYXRlIG5ldyBkaW1lbnNpb25zIG9mIHRoZSBoZWxwZXJcblxuXHR2YXIgaHggPSB0aGlzLmxpZ2h0LndpZHRoICogMC41O1xuXHR2YXIgaHkgPSB0aGlzLmxpZ2h0LmhlaWdodCAqIDAuNTtcblxuXHR2YXIgcG9zaXRpb24gPSBsaW5lLmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cdHZhciBhcnJheSA9IHBvc2l0aW9uLmFycmF5O1xuXG5cdC8vIHVwZGF0ZSB2ZXJ0aWNlc1xuXG5cdGFycmF5WyAgMCBdID0gICBoeDsgYXJyYXlbICAxIF0gPSAtIGh5OyBhcnJheVsgIDIgXSA9IDA7XG5cdGFycmF5WyAgMyBdID0gICBoeDsgYXJyYXlbICA0IF0gPSAgIGh5OyBhcnJheVsgIDUgXSA9IDA7XG5cdGFycmF5WyAgNiBdID0gLSBoeDsgYXJyYXlbICA3IF0gPSAgIGh5OyBhcnJheVsgIDggXSA9IDA7XG5cdGFycmF5WyAgOSBdID0gLSBoeDsgYXJyYXlbIDEwIF0gPSAtIGh5OyBhcnJheVsgMTEgXSA9IDA7XG5cdGFycmF5WyAxMiBdID0gICBoeDsgYXJyYXlbIDEzIF0gPSAtIGh5OyBhcnJheVsgMTQgXSA9IDA7XG5cblx0cG9zaXRpb24ubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG59O1xuXG4vKipcbiAqIEBhdXRob3IgYWx0ZXJlZHEgLyBodHRwOi8vYWx0ZXJlZHF1YWxpYS5jb20vXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cHM6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG5mdW5jdGlvbiBIZW1pc3BoZXJlTGlnaHRIZWxwZXIoIGxpZ2h0LCBzaXplICkge1xuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLmxpZ2h0ID0gbGlnaHQ7XG5cdHRoaXMubGlnaHQudXBkYXRlTWF0cml4V29ybGQoKTtcblxuXHR0aGlzLm1hdHJpeCA9IGxpZ2h0Lm1hdHJpeFdvcmxkO1xuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHR2YXIgZ2VvbWV0cnkgPSBuZXcgT2N0YWhlZHJvbkJ1ZmZlckdlb21ldHJ5KCBzaXplICk7XG5cdGdlb21ldHJ5LnJvdGF0ZVkoIE1hdGguUEkgKiAwLjUgKTtcblxuXHR2YXIgbWF0ZXJpYWwgPSBuZXcgTWVzaEJhc2ljTWF0ZXJpYWwoIHsgdmVydGV4Q29sb3JzOiBWZXJ0ZXhDb2xvcnMsIHdpcmVmcmFtZTogdHJ1ZSB9ICk7XG5cblx0dmFyIHBvc2l0aW9uID0gZ2VvbWV0cnkuZ2V0QXR0cmlidXRlKCAncG9zaXRpb24nICk7XG5cdHZhciBjb2xvcnMgPSBuZXcgRmxvYXQzMkFycmF5KCBwb3NpdGlvbi5jb3VudCAqIDMgKTtcblxuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdjb2xvcicsIG5ldyBCdWZmZXJBdHRyaWJ1dGUoIGNvbG9ycywgMyApICk7XG5cblx0dGhpcy5hZGQoIG5ldyBNZXNoKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSApO1xuXG5cdHRoaXMudXBkYXRlKCk7XG5cbn1cblxuSGVtaXNwaGVyZUxpZ2h0SGVscGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApO1xuSGVtaXNwaGVyZUxpZ2h0SGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEhlbWlzcGhlcmVMaWdodEhlbHBlcjtcblxuSGVtaXNwaGVyZUxpZ2h0SGVscGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXG5cdHRoaXMuY2hpbGRyZW5bIDAgXS5nZW9tZXRyeS5kaXNwb3NlKCk7XG5cdHRoaXMuY2hpbGRyZW5bIDAgXS5tYXRlcmlhbC5kaXNwb3NlKCk7XG5cbn07XG5cbkhlbWlzcGhlcmVMaWdodEhlbHBlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuXG5cdHZhciB2ZWN0b3IgPSBuZXcgVmVjdG9yMygpO1xuXG5cdHZhciBjb2xvcjEgPSBuZXcgQ29sb3IoKTtcblx0dmFyIGNvbG9yMiA9IG5ldyBDb2xvcigpO1xuXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGUoKSB7XG5cblx0XHR2YXIgbWVzaCA9IHRoaXMuY2hpbGRyZW5bIDAgXTtcblxuXHRcdHZhciBjb2xvcnMgPSBtZXNoLmdlb21ldHJ5LmdldEF0dHJpYnV0ZSggJ2NvbG9yJyApO1xuXG5cdFx0Y29sb3IxLmNvcHkoIHRoaXMubGlnaHQuY29sb3IgKTtcblx0XHRjb2xvcjIuY29weSggdGhpcy5saWdodC5ncm91bmRDb2xvciApO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gY29sb3JzLmNvdW50OyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0dmFyIGNvbG9yID0gKCBpIDwgKCBsIC8gMiApICkgPyBjb2xvcjEgOiBjb2xvcjI7XG5cblx0XHRcdGNvbG9ycy5zZXRYWVooIGksIGNvbG9yLnIsIGNvbG9yLmcsIGNvbG9yLmIgKTtcblxuXHRcdH1cblxuXHRcdG1lc2gubG9va0F0KCB2ZWN0b3Iuc2V0RnJvbU1hdHJpeFBvc2l0aW9uKCB0aGlzLmxpZ2h0Lm1hdHJpeFdvcmxkICkubmVnYXRlKCkgKTtcblxuXHRcdGNvbG9ycy5uZWVkc1VwZGF0ZSA9IHRydWU7XG5cblx0fTtcblxufSgpO1xuXG4vKipcbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gR3JpZEhlbHBlciggc2l6ZSwgZGl2aXNpb25zLCBjb2xvcjEsIGNvbG9yMiApIHtcblxuXHRzaXplID0gc2l6ZSB8fCAxMDtcblx0ZGl2aXNpb25zID0gZGl2aXNpb25zIHx8IDEwO1xuXHRjb2xvcjEgPSBuZXcgQ29sb3IoIGNvbG9yMSAhPT0gdW5kZWZpbmVkID8gY29sb3IxIDogMHg0NDQ0NDQgKTtcblx0Y29sb3IyID0gbmV3IENvbG9yKCBjb2xvcjIgIT09IHVuZGVmaW5lZCA/IGNvbG9yMiA6IDB4ODg4ODg4ICk7XG5cblx0dmFyIGNlbnRlciA9IGRpdmlzaW9ucyAvIDI7XG5cdHZhciBzdGVwID0gc2l6ZSAvIGRpdmlzaW9ucztcblx0dmFyIGhhbGZTaXplID0gc2l6ZSAvIDI7XG5cblx0dmFyIHZlcnRpY2VzID0gW10sIGNvbG9ycyA9IFtdO1xuXG5cdGZvciAoIHZhciBpID0gMCwgaiA9IDAsIGsgPSAtIGhhbGZTaXplOyBpIDw9IGRpdmlzaW9uczsgaSArKywgayArPSBzdGVwICkge1xuXG5cdFx0dmVydGljZXMucHVzaCggLSBoYWxmU2l6ZSwgMCwgaywgaGFsZlNpemUsIDAsIGsgKTtcblx0XHR2ZXJ0aWNlcy5wdXNoKCBrLCAwLCAtIGhhbGZTaXplLCBrLCAwLCBoYWxmU2l6ZSApO1xuXG5cdFx0dmFyIGNvbG9yID0gaSA9PT0gY2VudGVyID8gY29sb3IxIDogY29sb3IyO1xuXG5cdFx0Y29sb3IudG9BcnJheSggY29sb3JzLCBqICk7IGogKz0gMztcblx0XHRjb2xvci50b0FycmF5KCBjb2xvcnMsIGogKTsgaiArPSAzO1xuXHRcdGNvbG9yLnRvQXJyYXkoIGNvbG9ycywgaiApOyBqICs9IDM7XG5cdFx0Y29sb3IudG9BcnJheSggY29sb3JzLCBqICk7IGogKz0gMztcblxuXHR9XG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cdGdlb21ldHJ5LmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAnY29sb3InLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggY29sb3JzLCAzICkgKTtcblxuXHR2YXIgbWF0ZXJpYWwgPSBuZXcgTGluZUJhc2ljTWF0ZXJpYWwoIHsgdmVydGV4Q29sb3JzOiBWZXJ0ZXhDb2xvcnMgfSApO1xuXG5cdExpbmVTZWdtZW50cy5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcblxufVxuXG5HcmlkSGVscGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIExpbmVTZWdtZW50cy5wcm90b3R5cGUgKTtcbkdyaWRIZWxwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR3JpZEhlbHBlcjtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBNdWdlbjg3IC8gaHR0cDovL2dpdGh1Yi5jb20vTXVnZW44N1xuICogQGF1dGhvciBIZWN0YXRlIC8gaHR0cDovL3d3dy5naXRodWIuY29tL0hlY3RhdGVcbiAqL1xuXG5mdW5jdGlvbiBQb2xhckdyaWRIZWxwZXIoIHJhZGl1cywgcmFkaWFscywgY2lyY2xlcywgZGl2aXNpb25zLCBjb2xvcjEsIGNvbG9yMiApIHtcblxuXHRyYWRpdXMgPSByYWRpdXMgfHwgMTA7XG5cdHJhZGlhbHMgPSByYWRpYWxzIHx8IDE2O1xuXHRjaXJjbGVzID0gY2lyY2xlcyB8fCA4O1xuXHRkaXZpc2lvbnMgPSBkaXZpc2lvbnMgfHwgNjQ7XG5cdGNvbG9yMSA9IG5ldyBDb2xvciggY29sb3IxICE9PSB1bmRlZmluZWQgPyBjb2xvcjEgOiAweDQ0NDQ0NCApO1xuXHRjb2xvcjIgPSBuZXcgQ29sb3IoIGNvbG9yMiAhPT0gdW5kZWZpbmVkID8gY29sb3IyIDogMHg4ODg4ODggKTtcblxuXHR2YXIgdmVydGljZXMgPSBbXTtcblx0dmFyIGNvbG9ycyA9IFtdO1xuXG5cdHZhciB4LCB6O1xuXHR2YXIgdiwgaSwgaiwgciwgY29sb3I7XG5cblx0Ly8gY3JlYXRlIHRoZSByYWRpYWxzXG5cblx0Zm9yICggaSA9IDA7IGkgPD0gcmFkaWFsczsgaSArKyApIHtcblxuXHRcdHYgPSAoIGkgLyByYWRpYWxzICkgKiAoIE1hdGguUEkgKiAyICk7XG5cblx0XHR4ID0gTWF0aC5zaW4oIHYgKSAqIHJhZGl1cztcblx0XHR6ID0gTWF0aC5jb3MoIHYgKSAqIHJhZGl1cztcblxuXHRcdHZlcnRpY2VzLnB1c2goIDAsIDAsIDAgKTtcblx0XHR2ZXJ0aWNlcy5wdXNoKCB4LCAwLCB6ICk7XG5cblx0XHRjb2xvciA9ICggaSAmIDEgKSA/IGNvbG9yMSA6IGNvbG9yMjtcblxuXHRcdGNvbG9ycy5wdXNoKCBjb2xvci5yLCBjb2xvci5nLCBjb2xvci5iICk7XG5cdFx0Y29sb3JzLnB1c2goIGNvbG9yLnIsIGNvbG9yLmcsIGNvbG9yLmIgKTtcblxuXHR9XG5cblx0Ly8gY3JlYXRlIHRoZSBjaXJjbGVzXG5cblx0Zm9yICggaSA9IDA7IGkgPD0gY2lyY2xlczsgaSArKyApIHtcblxuXHRcdGNvbG9yID0gKCBpICYgMSApID8gY29sb3IxIDogY29sb3IyO1xuXG5cdFx0ciA9IHJhZGl1cyAtICggcmFkaXVzIC8gY2lyY2xlcyAqIGkgKTtcblxuXHRcdGZvciAoIGogPSAwOyBqIDwgZGl2aXNpb25zOyBqICsrICkge1xuXG5cdFx0XHQvLyBmaXJzdCB2ZXJ0ZXhcblxuXHRcdFx0diA9ICggaiAvIGRpdmlzaW9ucyApICogKCBNYXRoLlBJICogMiApO1xuXG5cdFx0XHR4ID0gTWF0aC5zaW4oIHYgKSAqIHI7XG5cdFx0XHR6ID0gTWF0aC5jb3MoIHYgKSAqIHI7XG5cblx0XHRcdHZlcnRpY2VzLnB1c2goIHgsIDAsIHogKTtcblx0XHRcdGNvbG9ycy5wdXNoKCBjb2xvci5yLCBjb2xvci5nLCBjb2xvci5iICk7XG5cblx0XHRcdC8vIHNlY29uZCB2ZXJ0ZXhcblxuXHRcdFx0diA9ICggKCBqICsgMSApIC8gZGl2aXNpb25zICkgKiAoIE1hdGguUEkgKiAyICk7XG5cblx0XHRcdHggPSBNYXRoLnNpbiggdiApICogcjtcblx0XHRcdHogPSBNYXRoLmNvcyggdiApICogcjtcblxuXHRcdFx0dmVydGljZXMucHVzaCggeCwgMCwgeiApO1xuXHRcdFx0Y29sb3JzLnB1c2goIGNvbG9yLnIsIGNvbG9yLmcsIGNvbG9yLmIgKTtcblxuXHRcdH1cblxuXHR9XG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cdGdlb21ldHJ5LmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIHZlcnRpY2VzLCAzICkgKTtcblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAnY29sb3InLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggY29sb3JzLCAzICkgKTtcblxuXHR2YXIgbWF0ZXJpYWwgPSBuZXcgTGluZUJhc2ljTWF0ZXJpYWwoIHsgdmVydGV4Q29sb3JzOiBWZXJ0ZXhDb2xvcnMgfSApO1xuXG5cdExpbmVTZWdtZW50cy5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcblxufVxuXG5Qb2xhckdyaWRIZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTGluZVNlZ21lbnRzLnByb3RvdHlwZSApO1xuUG9sYXJHcmlkSGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFBvbGFyR3JpZEhlbHBlcjtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4qL1xuXG5mdW5jdGlvbiBGYWNlTm9ybWFsc0hlbHBlciggb2JqZWN0LCBzaXplLCBoZXgsIGxpbmV3aWR0aCApIHtcblxuXHQvLyBGYWNlTm9ybWFsc0hlbHBlciBvbmx5IHN1cHBvcnRzIFRIUkVFLkdlb21ldHJ5XG5cblx0dGhpcy5vYmplY3QgPSBvYmplY3Q7XG5cblx0dGhpcy5zaXplID0gKCBzaXplICE9PSB1bmRlZmluZWQgKSA/IHNpemUgOiAxO1xuXG5cdHZhciBjb2xvciA9ICggaGV4ICE9PSB1bmRlZmluZWQgKSA/IGhleCA6IDB4ZmZmZjAwO1xuXG5cdHZhciB3aWR0aCA9ICggbGluZXdpZHRoICE9PSB1bmRlZmluZWQgKSA/IGxpbmV3aWR0aCA6IDE7XG5cblx0Ly9cblxuXHR2YXIgbk5vcm1hbHMgPSAwO1xuXG5cdHZhciBvYmpHZW9tZXRyeSA9IHRoaXMub2JqZWN0Lmdlb21ldHJ5O1xuXG5cdGlmICggb2JqR2VvbWV0cnkgJiYgb2JqR2VvbWV0cnkuaXNHZW9tZXRyeSApIHtcblxuXHRcdG5Ob3JtYWxzID0gb2JqR2VvbWV0cnkuZmFjZXMubGVuZ3RoO1xuXG5cdH0gZWxzZSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5GYWNlTm9ybWFsc0hlbHBlcjogb25seSBUSFJFRS5HZW9tZXRyeSBpcyBzdXBwb3J0ZWQuIFVzZSBUSFJFRS5WZXJ0ZXhOb3JtYWxzSGVscGVyLCBpbnN0ZWFkLicgKTtcblxuXHR9XG5cblx0Ly9cblxuXHR2YXIgZ2VvbWV0cnkgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKTtcblxuXHR2YXIgcG9zaXRpb25zID0gbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIG5Ob3JtYWxzICogMiAqIDMsIDMgKTtcblxuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIHBvc2l0aW9ucyApO1xuXG5cdExpbmVTZWdtZW50cy5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbmV3IExpbmVCYXNpY01hdGVyaWFsKCB7IGNvbG9yOiBjb2xvciwgbGluZXdpZHRoOiB3aWR0aCB9ICkgKTtcblxuXHQvL1xuXG5cdHRoaXMubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXHR0aGlzLnVwZGF0ZSgpO1xuXG59XG5cbkZhY2VOb3JtYWxzSGVscGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIExpbmVTZWdtZW50cy5wcm90b3R5cGUgKTtcbkZhY2VOb3JtYWxzSGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEZhY2VOb3JtYWxzSGVscGVyO1xuXG5GYWNlTm9ybWFsc0hlbHBlci5wcm90b3R5cGUudXBkYXRlID0gKCBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIHYxID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIHYyID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIG5vcm1hbE1hdHJpeCA9IG5ldyBNYXRyaXgzKCk7XG5cblx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcblxuXHRcdHRoaXMub2JqZWN0LnVwZGF0ZU1hdHJpeFdvcmxkKCB0cnVlICk7XG5cblx0XHRub3JtYWxNYXRyaXguZ2V0Tm9ybWFsTWF0cml4KCB0aGlzLm9iamVjdC5tYXRyaXhXb3JsZCApO1xuXG5cdFx0dmFyIG1hdHJpeFdvcmxkID0gdGhpcy5vYmplY3QubWF0cml4V29ybGQ7XG5cblx0XHR2YXIgcG9zaXRpb24gPSB0aGlzLmdlb21ldHJ5LmF0dHJpYnV0ZXMucG9zaXRpb247XG5cblx0XHQvL1xuXG5cdFx0dmFyIG9iakdlb21ldHJ5ID0gdGhpcy5vYmplY3QuZ2VvbWV0cnk7XG5cblx0XHR2YXIgdmVydGljZXMgPSBvYmpHZW9tZXRyeS52ZXJ0aWNlcztcblxuXHRcdHZhciBmYWNlcyA9IG9iakdlb21ldHJ5LmZhY2VzO1xuXG5cdFx0dmFyIGlkeCA9IDA7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBmYWNlcy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHR2YXIgZmFjZSA9IGZhY2VzWyBpIF07XG5cblx0XHRcdHZhciBub3JtYWwgPSBmYWNlLm5vcm1hbDtcblxuXHRcdFx0djEuY29weSggdmVydGljZXNbIGZhY2UuYSBdIClcblx0XHRcdFx0LmFkZCggdmVydGljZXNbIGZhY2UuYiBdIClcblx0XHRcdFx0LmFkZCggdmVydGljZXNbIGZhY2UuYyBdIClcblx0XHRcdFx0LmRpdmlkZVNjYWxhciggMyApXG5cdFx0XHRcdC5hcHBseU1hdHJpeDQoIG1hdHJpeFdvcmxkICk7XG5cblx0XHRcdHYyLmNvcHkoIG5vcm1hbCApLmFwcGx5TWF0cml4Myggbm9ybWFsTWF0cml4ICkubm9ybWFsaXplKCkubXVsdGlwbHlTY2FsYXIoIHRoaXMuc2l6ZSApLmFkZCggdjEgKTtcblxuXHRcdFx0cG9zaXRpb24uc2V0WFlaKCBpZHgsIHYxLngsIHYxLnksIHYxLnogKTtcblxuXHRcdFx0aWR4ID0gaWR4ICsgMTtcblxuXHRcdFx0cG9zaXRpb24uc2V0WFlaKCBpZHgsIHYyLngsIHYyLnksIHYyLnogKTtcblxuXHRcdFx0aWR4ID0gaWR4ICsgMTtcblxuXHRcdH1cblxuXHRcdHBvc2l0aW9uLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHR9O1xuXG59KCkgKTtcblxuLyoqXG4gKiBAYXV0aG9yIGFsdGVyZWRxIC8gaHR0cDovL2FsdGVyZWRxdWFsaWEuY29tL1xuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgV2VzdExhbmdsZXkgLyBodHRwOi8vZ2l0aHViLmNvbS9XZXN0TGFuZ2xleVxuICovXG5cbmZ1bmN0aW9uIERpcmVjdGlvbmFsTGlnaHRIZWxwZXIoIGxpZ2h0LCBzaXplICkge1xuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLmxpZ2h0ID0gbGlnaHQ7XG5cdHRoaXMubGlnaHQudXBkYXRlTWF0cml4V29ybGQoKTtcblxuXHR0aGlzLm1hdHJpeCA9IGxpZ2h0Lm1hdHJpeFdvcmxkO1xuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHRpZiAoIHNpemUgPT09IHVuZGVmaW5lZCApIHNpemUgPSAxO1xuXG5cdHZhciBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBbXG5cdFx0LSBzaXplLCAgIHNpemUsIDAsXG5cdFx0ICBzaXplLCAgIHNpemUsIDAsXG5cdFx0ICBzaXplLCAtIHNpemUsIDAsXG5cdFx0LSBzaXplLCAtIHNpemUsIDAsXG5cdFx0LSBzaXplLCAgIHNpemUsIDBcblx0XSwgMyApICk7XG5cblx0dmFyIG1hdGVyaWFsID0gbmV3IExpbmVCYXNpY01hdGVyaWFsKCB7IGZvZzogZmFsc2UgfSApO1xuXG5cdHRoaXMuYWRkKCBuZXcgTGluZSggZ2VvbWV0cnksIG1hdGVyaWFsICkgKTtcblxuXHRnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBbIDAsIDAsIDAsIDAsIDAsIDEgXSwgMyApICk7XG5cblx0dGhpcy5hZGQoIG5ldyBMaW5lKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSk7XG5cblx0dGhpcy51cGRhdGUoKTtcblxufVxuXG5EaXJlY3Rpb25hbExpZ2h0SGVscGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIE9iamVjdDNELnByb3RvdHlwZSApO1xuRGlyZWN0aW9uYWxMaWdodEhlbHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBEaXJlY3Rpb25hbExpZ2h0SGVscGVyO1xuXG5EaXJlY3Rpb25hbExpZ2h0SGVscGVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuXG5cdHZhciBsaWdodFBsYW5lID0gdGhpcy5jaGlsZHJlblsgMCBdO1xuXHR2YXIgdGFyZ2V0TGluZSA9IHRoaXMuY2hpbGRyZW5bIDEgXTtcblxuXHRsaWdodFBsYW5lLmdlb21ldHJ5LmRpc3Bvc2UoKTtcblx0bGlnaHRQbGFuZS5tYXRlcmlhbC5kaXNwb3NlKCk7XG5cdHRhcmdldExpbmUuZ2VvbWV0cnkuZGlzcG9zZSgpO1xuXHR0YXJnZXRMaW5lLm1hdGVyaWFsLmRpc3Bvc2UoKTtcblxufTtcblxuRGlyZWN0aW9uYWxMaWdodEhlbHBlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuXG5cdHZhciB2MSA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciB2MiA9IG5ldyBWZWN0b3IzKCk7XG5cdHZhciB2MyA9IG5ldyBWZWN0b3IzKCk7XG5cblx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcblxuXHRcdHYxLnNldEZyb21NYXRyaXhQb3NpdGlvbiggdGhpcy5saWdodC5tYXRyaXhXb3JsZCApO1xuXHRcdHYyLnNldEZyb21NYXRyaXhQb3NpdGlvbiggdGhpcy5saWdodC50YXJnZXQubWF0cml4V29ybGQgKTtcblx0XHR2My5zdWJWZWN0b3JzKCB2MiwgdjEgKTtcblxuXHRcdHZhciBsaWdodFBsYW5lID0gdGhpcy5jaGlsZHJlblsgMCBdO1xuXHRcdHZhciB0YXJnZXRMaW5lID0gdGhpcy5jaGlsZHJlblsgMSBdO1xuXG5cdFx0bGlnaHRQbGFuZS5sb29rQXQoIHYzICk7XG5cdFx0bGlnaHRQbGFuZS5tYXRlcmlhbC5jb2xvci5jb3B5KCB0aGlzLmxpZ2h0LmNvbG9yICk7XG5cblx0XHR0YXJnZXRMaW5lLmxvb2tBdCggdjMgKTtcblx0XHR0YXJnZXRMaW5lLnNjYWxlLnogPSB2My5sZW5ndGgoKTtcblxuXHR9O1xuXG59KCk7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHBzOi8vZ2l0aHViLmNvbS9NdWdlbjg3XG4gKlxuICpcdC0gc2hvd3MgZnJ1c3R1bSwgbGluZSBvZiBzaWdodCBhbmQgdXAgb2YgdGhlIGNhbWVyYVxuICpcdC0gc3VpdGFibGUgZm9yIGZhc3QgdXBkYXRlc1xuICogXHQtIGJhc2VkIG9uIGZydXN0dW0gdmlzdWFsaXphdGlvbiBpbiBsaWdodGdsLmpzIHNoYWRvd21hcCBleGFtcGxlXG4gKlx0XHRodHRwOi8vZXZhbncuZ2l0aHViLmNvbS9saWdodGdsLmpzL3Rlc3RzL3NoYWRvd21hcC5odG1sXG4gKi9cblxuZnVuY3Rpb24gQ2FtZXJhSGVscGVyKCBjYW1lcmEgKSB7XG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cdHZhciBtYXRlcmlhbCA9IG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogMHhmZmZmZmYsIHZlcnRleENvbG9yczogRmFjZUNvbG9ycyB9ICk7XG5cblx0dmFyIHZlcnRpY2VzID0gW107XG5cdHZhciBjb2xvcnMgPSBbXTtcblxuXHR2YXIgcG9pbnRNYXAgPSB7fTtcblxuXHQvLyBjb2xvcnNcblxuXHR2YXIgY29sb3JGcnVzdHVtID0gbmV3IENvbG9yKCAweGZmYWEwMCApO1xuXHR2YXIgY29sb3JDb25lID0gbmV3IENvbG9yKCAweGZmMDAwMCApO1xuXHR2YXIgY29sb3JVcCA9IG5ldyBDb2xvciggMHgwMGFhZmYgKTtcblx0dmFyIGNvbG9yVGFyZ2V0ID0gbmV3IENvbG9yKCAweGZmZmZmZiApO1xuXHR2YXIgY29sb3JDcm9zcyA9IG5ldyBDb2xvciggMHgzMzMzMzMgKTtcblxuXHQvLyBuZWFyXG5cblx0YWRkTGluZSggXCJuMVwiLCBcIm4yXCIsIGNvbG9yRnJ1c3R1bSApO1xuXHRhZGRMaW5lKCBcIm4yXCIsIFwibjRcIiwgY29sb3JGcnVzdHVtICk7XG5cdGFkZExpbmUoIFwibjRcIiwgXCJuM1wiLCBjb2xvckZydXN0dW0gKTtcblx0YWRkTGluZSggXCJuM1wiLCBcIm4xXCIsIGNvbG9yRnJ1c3R1bSApO1xuXG5cdC8vIGZhclxuXG5cdGFkZExpbmUoIFwiZjFcIiwgXCJmMlwiLCBjb2xvckZydXN0dW0gKTtcblx0YWRkTGluZSggXCJmMlwiLCBcImY0XCIsIGNvbG9yRnJ1c3R1bSApO1xuXHRhZGRMaW5lKCBcImY0XCIsIFwiZjNcIiwgY29sb3JGcnVzdHVtICk7XG5cdGFkZExpbmUoIFwiZjNcIiwgXCJmMVwiLCBjb2xvckZydXN0dW0gKTtcblxuXHQvLyBzaWRlc1xuXG5cdGFkZExpbmUoIFwibjFcIiwgXCJmMVwiLCBjb2xvckZydXN0dW0gKTtcblx0YWRkTGluZSggXCJuMlwiLCBcImYyXCIsIGNvbG9yRnJ1c3R1bSApO1xuXHRhZGRMaW5lKCBcIm4zXCIsIFwiZjNcIiwgY29sb3JGcnVzdHVtICk7XG5cdGFkZExpbmUoIFwibjRcIiwgXCJmNFwiLCBjb2xvckZydXN0dW0gKTtcblxuXHQvLyBjb25lXG5cblx0YWRkTGluZSggXCJwXCIsIFwibjFcIiwgY29sb3JDb25lICk7XG5cdGFkZExpbmUoIFwicFwiLCBcIm4yXCIsIGNvbG9yQ29uZSApO1xuXHRhZGRMaW5lKCBcInBcIiwgXCJuM1wiLCBjb2xvckNvbmUgKTtcblx0YWRkTGluZSggXCJwXCIsIFwibjRcIiwgY29sb3JDb25lICk7XG5cblx0Ly8gdXBcblxuXHRhZGRMaW5lKCBcInUxXCIsIFwidTJcIiwgY29sb3JVcCApO1xuXHRhZGRMaW5lKCBcInUyXCIsIFwidTNcIiwgY29sb3JVcCApO1xuXHRhZGRMaW5lKCBcInUzXCIsIFwidTFcIiwgY29sb3JVcCApO1xuXG5cdC8vIHRhcmdldFxuXG5cdGFkZExpbmUoIFwiY1wiLCBcInRcIiwgY29sb3JUYXJnZXQgKTtcblx0YWRkTGluZSggXCJwXCIsIFwiY1wiLCBjb2xvckNyb3NzICk7XG5cblx0Ly8gY3Jvc3NcblxuXHRhZGRMaW5lKCBcImNuMVwiLCBcImNuMlwiLCBjb2xvckNyb3NzICk7XG5cdGFkZExpbmUoIFwiY24zXCIsIFwiY240XCIsIGNvbG9yQ3Jvc3MgKTtcblxuXHRhZGRMaW5lKCBcImNmMVwiLCBcImNmMlwiLCBjb2xvckNyb3NzICk7XG5cdGFkZExpbmUoIFwiY2YzXCIsIFwiY2Y0XCIsIGNvbG9yQ3Jvc3MgKTtcblxuXHRmdW5jdGlvbiBhZGRMaW5lKCBhLCBiLCBjb2xvciApIHtcblxuXHRcdGFkZFBvaW50KCBhLCBjb2xvciApO1xuXHRcdGFkZFBvaW50KCBiLCBjb2xvciApO1xuXG5cdH1cblxuXHRmdW5jdGlvbiBhZGRQb2ludCggaWQsIGNvbG9yICkge1xuXG5cdFx0dmVydGljZXMucHVzaCggMCwgMCwgMCApO1xuXHRcdGNvbG9ycy5wdXNoKCBjb2xvci5yLCBjb2xvci5nLCBjb2xvci5iICk7XG5cblx0XHRpZiAoIHBvaW50TWFwWyBpZCBdID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHBvaW50TWFwWyBpZCBdID0gW107XG5cblx0XHR9XG5cblx0XHRwb2ludE1hcFsgaWQgXS5wdXNoKCAoIHZlcnRpY2VzLmxlbmd0aCAvIDMgKSAtIDEgKTtcblxuXHR9XG5cblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdjb2xvcicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBjb2xvcnMsIDMgKSApO1xuXG5cdExpbmVTZWdtZW50cy5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcblxuXHR0aGlzLmNhbWVyYSA9IGNhbWVyYTtcblx0aWYgKCB0aGlzLmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4ICkgdGhpcy5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuXG5cdHRoaXMubWF0cml4ID0gY2FtZXJhLm1hdHJpeFdvcmxkO1xuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLnBvaW50TWFwID0gcG9pbnRNYXA7XG5cblx0dGhpcy51cGRhdGUoKTtcblxufVxuXG5DYW1lcmFIZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTGluZVNlZ21lbnRzLnByb3RvdHlwZSApO1xuQ2FtZXJhSGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IENhbWVyYUhlbHBlcjtcblxuQ2FtZXJhSGVscGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIGdlb21ldHJ5LCBwb2ludE1hcDtcblxuXHR2YXIgdmVjdG9yID0gbmV3IFZlY3RvcjMoKTtcblx0dmFyIGNhbWVyYSA9IG5ldyBDYW1lcmEoKTtcblxuXHRmdW5jdGlvbiBzZXRQb2ludCggcG9pbnQsIHgsIHksIHogKSB7XG5cblx0XHR2ZWN0b3Iuc2V0KCB4LCB5LCB6ICkudW5wcm9qZWN0KCBjYW1lcmEgKTtcblxuXHRcdHZhciBwb2ludHMgPSBwb2ludE1hcFsgcG9pbnQgXTtcblxuXHRcdGlmICggcG9pbnRzICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdHZhciBwb3NpdGlvbiA9IGdlb21ldHJ5LmdldEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJyApO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDAsIGwgPSBwb2ludHMubGVuZ3RoOyBpIDwgbDsgaSArKyApIHtcblxuXHRcdFx0XHRwb3NpdGlvbi5zZXRYWVooIHBvaW50c1sgaSBdLCB2ZWN0b3IueCwgdmVjdG9yLnksIHZlY3Rvci56ICk7XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHR9XG5cblx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcblxuXHRcdGdlb21ldHJ5ID0gdGhpcy5nZW9tZXRyeTtcblx0XHRwb2ludE1hcCA9IHRoaXMucG9pbnRNYXA7XG5cblx0XHR2YXIgdyA9IDEsIGggPSAxO1xuXG5cdFx0Ly8gd2UgbmVlZCBqdXN0IGNhbWVyYSBwcm9qZWN0aW9uIG1hdHJpeFxuXHRcdC8vIHdvcmxkIG1hdHJpeCBtdXN0IGJlIGlkZW50aXR5XG5cblx0XHRjYW1lcmEucHJvamVjdGlvbk1hdHJpeC5jb3B5KCB0aGlzLmNhbWVyYS5wcm9qZWN0aW9uTWF0cml4ICk7XG5cblx0XHQvLyBjZW50ZXIgLyB0YXJnZXRcblxuXHRcdHNldFBvaW50KCBcImNcIiwgMCwgMCwgLSAxICk7XG5cdFx0c2V0UG9pbnQoIFwidFwiLCAwLCAwLCAgMSApO1xuXG5cdFx0Ly8gbmVhclxuXG5cdFx0c2V0UG9pbnQoIFwibjFcIiwgLSB3LCAtIGgsIC0gMSApO1xuXHRcdHNldFBvaW50KCBcIm4yXCIsICAgdywgLSBoLCAtIDEgKTtcblx0XHRzZXRQb2ludCggXCJuM1wiLCAtIHcsICAgaCwgLSAxICk7XG5cdFx0c2V0UG9pbnQoIFwibjRcIiwgICB3LCAgIGgsIC0gMSApO1xuXG5cdFx0Ly8gZmFyXG5cblx0XHRzZXRQb2ludCggXCJmMVwiLCAtIHcsIC0gaCwgMSApO1xuXHRcdHNldFBvaW50KCBcImYyXCIsICAgdywgLSBoLCAxICk7XG5cdFx0c2V0UG9pbnQoIFwiZjNcIiwgLSB3LCAgIGgsIDEgKTtcblx0XHRzZXRQb2ludCggXCJmNFwiLCAgIHcsICAgaCwgMSApO1xuXG5cdFx0Ly8gdXBcblxuXHRcdHNldFBvaW50KCBcInUxXCIsICAgdyAqIDAuNywgaCAqIDEuMSwgLSAxICk7XG5cdFx0c2V0UG9pbnQoIFwidTJcIiwgLSB3ICogMC43LCBoICogMS4xLCAtIDEgKTtcblx0XHRzZXRQb2ludCggXCJ1M1wiLCAgICAgICAgIDAsIGggKiAyLCAgIC0gMSApO1xuXG5cdFx0Ly8gY3Jvc3NcblxuXHRcdHNldFBvaW50KCBcImNmMVwiLCAtIHcsICAgMCwgMSApO1xuXHRcdHNldFBvaW50KCBcImNmMlwiLCAgIHcsICAgMCwgMSApO1xuXHRcdHNldFBvaW50KCBcImNmM1wiLCAgIDAsIC0gaCwgMSApO1xuXHRcdHNldFBvaW50KCBcImNmNFwiLCAgIDAsICAgaCwgMSApO1xuXG5cdFx0c2V0UG9pbnQoIFwiY24xXCIsIC0gdywgICAwLCAtIDEgKTtcblx0XHRzZXRQb2ludCggXCJjbjJcIiwgICB3LCAgIDAsIC0gMSApO1xuXHRcdHNldFBvaW50KCBcImNuM1wiLCAgIDAsIC0gaCwgLSAxICk7XG5cdFx0c2V0UG9pbnQoIFwiY240XCIsICAgMCwgICBoLCAtIDEgKTtcblxuXHRcdGdlb21ldHJ5LmdldEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJyApLm5lZWRzVXBkYXRlID0gdHJ1ZTtcblxuXHR9O1xuXG59KCk7XG5cbi8qKlxuICogQGF1dGhvciBtcmRvb2IgLyBodHRwOi8vbXJkb29iLmNvbS9cbiAqIEBhdXRob3IgTXVnZW44NyAvIGh0dHA6Ly9naXRodWIuY29tL011Z2VuODdcbiAqL1xuXG5mdW5jdGlvbiBCb3hIZWxwZXIoIG9iamVjdCwgY29sb3IgKSB7XG5cblx0dGhpcy5vYmplY3QgPSBvYmplY3Q7XG5cblx0aWYgKCBjb2xvciA9PT0gdW5kZWZpbmVkICkgY29sb3IgPSAweGZmZmYwMDtcblxuXHR2YXIgaW5kaWNlcyA9IG5ldyBVaW50MTZBcnJheSggWyAwLCAxLCAxLCAyLCAyLCAzLCAzLCAwLCA0LCA1LCA1LCA2LCA2LCA3LCA3LCA0LCAwLCA0LCAxLCA1LCAyLCA2LCAzLCA3IF0gKTtcblx0dmFyIHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkoIDggKiAzICk7XG5cblx0dmFyIGdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cdGdlb21ldHJ5LnNldEluZGV4KCBuZXcgQnVmZmVyQXR0cmlidXRlKCBpbmRpY2VzLCAxICkgKTtcblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgQnVmZmVyQXR0cmlidXRlKCBwb3NpdGlvbnMsIDMgKSApO1xuXG5cdExpbmVTZWdtZW50cy5jYWxsKCB0aGlzLCBnZW9tZXRyeSwgbmV3IExpbmVCYXNpY01hdGVyaWFsKCB7IGNvbG9yOiBjb2xvciB9ICkgKTtcblxuXHR0aGlzLm1hdHJpeEF1dG9VcGRhdGUgPSBmYWxzZTtcblxuXHR0aGlzLnVwZGF0ZSgpO1xuXG59XG5cbkJveEhlbHBlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBMaW5lU2VnbWVudHMucHJvdG90eXBlICk7XG5Cb3hIZWxwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQm94SGVscGVyO1xuXG5Cb3hIZWxwZXIucHJvdG90eXBlLnVwZGF0ZSA9ICggZnVuY3Rpb24gKCkge1xuXG5cdHZhciBib3ggPSBuZXcgQm94MygpO1xuXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGUoIG9iamVjdCApIHtcblxuXHRcdGlmICggb2JqZWN0ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJveEhlbHBlcjogLnVwZGF0ZSgpIGhhcyBubyBsb25nZXIgYXJndW1lbnRzLicgKTtcblxuXHRcdH1cblxuXHRcdGlmICggdGhpcy5vYmplY3QgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ym94LnNldEZyb21PYmplY3QoIHRoaXMub2JqZWN0ICk7XG5cblx0XHR9XG5cblx0XHRpZiAoIGJveC5pc0VtcHR5KCkgKSByZXR1cm47XG5cblx0XHR2YXIgbWluID0gYm94Lm1pbjtcblx0XHR2YXIgbWF4ID0gYm94Lm1heDtcblxuXHRcdC8qXG5cdFx0ICA1X19fXzRcblx0XHQxL19fXzAvfFxuXHRcdHwgNl9ffF83XG5cdFx0Mi9fX18zL1xuXG5cdFx0MDogbWF4LngsIG1heC55LCBtYXguelxuXHRcdDE6IG1pbi54LCBtYXgueSwgbWF4Lnpcblx0XHQyOiBtaW4ueCwgbWluLnksIG1heC56XG5cdFx0MzogbWF4LngsIG1pbi55LCBtYXguelxuXHRcdDQ6IG1heC54LCBtYXgueSwgbWluLnpcblx0XHQ1OiBtaW4ueCwgbWF4LnksIG1pbi56XG5cdFx0NjogbWluLngsIG1pbi55LCBtaW4uelxuXHRcdDc6IG1heC54LCBtaW4ueSwgbWluLnpcblx0XHQqL1xuXG5cdFx0dmFyIHBvc2l0aW9uID0gdGhpcy5nZW9tZXRyeS5hdHRyaWJ1dGVzLnBvc2l0aW9uO1xuXHRcdHZhciBhcnJheSA9IHBvc2l0aW9uLmFycmF5O1xuXG5cdFx0YXJyYXlbICAwIF0gPSBtYXgueDsgYXJyYXlbICAxIF0gPSBtYXgueTsgYXJyYXlbICAyIF0gPSBtYXguejtcblx0XHRhcnJheVsgIDMgXSA9IG1pbi54OyBhcnJheVsgIDQgXSA9IG1heC55OyBhcnJheVsgIDUgXSA9IG1heC56O1xuXHRcdGFycmF5WyAgNiBdID0gbWluLng7IGFycmF5WyAgNyBdID0gbWluLnk7IGFycmF5WyAgOCBdID0gbWF4Lno7XG5cdFx0YXJyYXlbICA5IF0gPSBtYXgueDsgYXJyYXlbIDEwIF0gPSBtaW4ueTsgYXJyYXlbIDExIF0gPSBtYXguejtcblx0XHRhcnJheVsgMTIgXSA9IG1heC54OyBhcnJheVsgMTMgXSA9IG1heC55OyBhcnJheVsgMTQgXSA9IG1pbi56O1xuXHRcdGFycmF5WyAxNSBdID0gbWluLng7IGFycmF5WyAxNiBdID0gbWF4Lnk7IGFycmF5WyAxNyBdID0gbWluLno7XG5cdFx0YXJyYXlbIDE4IF0gPSBtaW4ueDsgYXJyYXlbIDE5IF0gPSBtaW4ueTsgYXJyYXlbIDIwIF0gPSBtaW4uejtcblx0XHRhcnJheVsgMjEgXSA9IG1heC54OyBhcnJheVsgMjIgXSA9IG1pbi55OyBhcnJheVsgMjMgXSA9IG1pbi56O1xuXG5cdFx0cG9zaXRpb24ubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG5cdFx0dGhpcy5nZW9tZXRyeS5jb21wdXRlQm91bmRpbmdTcGhlcmUoKTtcblxuXHR9O1xuXG59ICkoKTtcblxuQm94SGVscGVyLnByb3RvdHlwZS5zZXRGcm9tT2JqZWN0ID0gZnVuY3Rpb24gKCBvYmplY3QgKSB7XG5cblx0dGhpcy5vYmplY3QgPSBvYmplY3Q7XG5cdHRoaXMudXBkYXRlKCk7XG5cblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbi8qKlxuICogQGF1dGhvciBXZXN0TGFuZ2xleSAvIGh0dHA6Ly9naXRodWIuY29tL1dlc3RMYW5nbGV5XG4gKiBAYXV0aG9yIHp6ODUgLyBodHRwOi8vZ2l0aHViLmNvbS96ejg1XG4gKiBAYXV0aG9yIGJob3VzdG9uIC8gaHR0cDovL2NsYXJhLmlvXG4gKlxuICogQ3JlYXRlcyBhbiBhcnJvdyBmb3IgdmlzdWFsaXppbmcgZGlyZWN0aW9uc1xuICpcbiAqIFBhcmFtZXRlcnM6XG4gKiAgZGlyIC0gVmVjdG9yM1xuICogIG9yaWdpbiAtIFZlY3RvcjNcbiAqICBsZW5ndGggLSBOdW1iZXJcbiAqICBjb2xvciAtIGNvbG9yIGluIGhleCB2YWx1ZVxuICogIGhlYWRMZW5ndGggLSBOdW1iZXJcbiAqICBoZWFkV2lkdGggLSBOdW1iZXJcbiAqL1xuXG52YXIgbGluZUdlb21ldHJ5O1xudmFyIGNvbmVHZW9tZXRyeTtcblxuZnVuY3Rpb24gQXJyb3dIZWxwZXIoIGRpciwgb3JpZ2luLCBsZW5ndGgsIGNvbG9yLCBoZWFkTGVuZ3RoLCBoZWFkV2lkdGggKSB7XG5cblx0Ly8gZGlyIGlzIGFzc3VtZWQgdG8gYmUgbm9ybWFsaXplZFxuXG5cdE9iamVjdDNELmNhbGwoIHRoaXMgKTtcblxuXHRpZiAoIGNvbG9yID09PSB1bmRlZmluZWQgKSBjb2xvciA9IDB4ZmZmZjAwO1xuXHRpZiAoIGxlbmd0aCA9PT0gdW5kZWZpbmVkICkgbGVuZ3RoID0gMTtcblx0aWYgKCBoZWFkTGVuZ3RoID09PSB1bmRlZmluZWQgKSBoZWFkTGVuZ3RoID0gMC4yICogbGVuZ3RoO1xuXHRpZiAoIGhlYWRXaWR0aCA9PT0gdW5kZWZpbmVkICkgaGVhZFdpZHRoID0gMC4yICogaGVhZExlbmd0aDtcblxuXHRpZiAoIGxpbmVHZW9tZXRyeSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0bGluZUdlb21ldHJ5ID0gbmV3IEJ1ZmZlckdlb21ldHJ5KCk7XG5cdFx0bGluZUdlb21ldHJ5LmFkZEF0dHJpYnV0ZSggJ3Bvc2l0aW9uJywgbmV3IEZsb2F0MzJCdWZmZXJBdHRyaWJ1dGUoIFsgMCwgMCwgMCwgMCwgMSwgMCBdLCAzICkgKTtcblxuXHRcdGNvbmVHZW9tZXRyeSA9IG5ldyBDeWxpbmRlckJ1ZmZlckdlb21ldHJ5KCAwLCAwLjUsIDEsIDUsIDEgKTtcblx0XHRjb25lR2VvbWV0cnkudHJhbnNsYXRlKCAwLCAtIDAuNSwgMCApO1xuXG5cdH1cblxuXHR0aGlzLnBvc2l0aW9uLmNvcHkoIG9yaWdpbiApO1xuXG5cdHRoaXMubGluZSA9IG5ldyBMaW5lKCBsaW5lR2VvbWV0cnksIG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyBjb2xvcjogY29sb3IgfSApICk7XG5cdHRoaXMubGluZS5tYXRyaXhBdXRvVXBkYXRlID0gZmFsc2U7XG5cdHRoaXMuYWRkKCB0aGlzLmxpbmUgKTtcblxuXHR0aGlzLmNvbmUgPSBuZXcgTWVzaCggY29uZUdlb21ldHJ5LCBuZXcgTWVzaEJhc2ljTWF0ZXJpYWwoIHsgY29sb3I6IGNvbG9yIH0gKSApO1xuXHR0aGlzLmNvbmUubWF0cml4QXV0b1VwZGF0ZSA9IGZhbHNlO1xuXHR0aGlzLmFkZCggdGhpcy5jb25lICk7XG5cblx0dGhpcy5zZXREaXJlY3Rpb24oIGRpciApO1xuXHR0aGlzLnNldExlbmd0aCggbGVuZ3RoLCBoZWFkTGVuZ3RoLCBoZWFkV2lkdGggKTtcblxufVxuXG5BcnJvd0hlbHBlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBPYmplY3QzRC5wcm90b3R5cGUgKTtcbkFycm93SGVscGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEFycm93SGVscGVyO1xuXG5BcnJvd0hlbHBlci5wcm90b3R5cGUuc2V0RGlyZWN0aW9uID0gKCBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIGF4aXMgPSBuZXcgVmVjdG9yMygpO1xuXHR2YXIgcmFkaWFucztcblxuXHRyZXR1cm4gZnVuY3Rpb24gc2V0RGlyZWN0aW9uKCBkaXIgKSB7XG5cblx0XHQvLyBkaXIgaXMgYXNzdW1lZCB0byBiZSBub3JtYWxpemVkXG5cblx0XHRpZiAoIGRpci55ID4gMC45OTk5OSApIHtcblxuXHRcdFx0dGhpcy5xdWF0ZXJuaW9uLnNldCggMCwgMCwgMCwgMSApO1xuXG5cdFx0fSBlbHNlIGlmICggZGlyLnkgPCAtIDAuOTk5OTkgKSB7XG5cblx0XHRcdHRoaXMucXVhdGVybmlvbi5zZXQoIDEsIDAsIDAsIDAgKTtcblxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGF4aXMuc2V0KCBkaXIueiwgMCwgLSBkaXIueCApLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHRyYWRpYW5zID0gTWF0aC5hY29zKCBkaXIueSApO1xuXG5cdFx0XHR0aGlzLnF1YXRlcm5pb24uc2V0RnJvbUF4aXNBbmdsZSggYXhpcywgcmFkaWFucyApO1xuXG5cdFx0fVxuXG5cdH07XG5cbn0oKSApO1xuXG5BcnJvd0hlbHBlci5wcm90b3R5cGUuc2V0TGVuZ3RoID0gZnVuY3Rpb24gKCBsZW5ndGgsIGhlYWRMZW5ndGgsIGhlYWRXaWR0aCApIHtcblxuXHRpZiAoIGhlYWRMZW5ndGggPT09IHVuZGVmaW5lZCApIGhlYWRMZW5ndGggPSAwLjIgKiBsZW5ndGg7XG5cdGlmICggaGVhZFdpZHRoID09PSB1bmRlZmluZWQgKSBoZWFkV2lkdGggPSAwLjIgKiBoZWFkTGVuZ3RoO1xuXG5cdHRoaXMubGluZS5zY2FsZS5zZXQoIDEsIE1hdGgubWF4KCAwLCBsZW5ndGggLSBoZWFkTGVuZ3RoICksIDEgKTtcblx0dGhpcy5saW5lLnVwZGF0ZU1hdHJpeCgpO1xuXG5cdHRoaXMuY29uZS5zY2FsZS5zZXQoIGhlYWRXaWR0aCwgaGVhZExlbmd0aCwgaGVhZFdpZHRoICk7XG5cdHRoaXMuY29uZS5wb3NpdGlvbi55ID0gbGVuZ3RoO1xuXHR0aGlzLmNvbmUudXBkYXRlTWF0cml4KCk7XG5cbn07XG5cbkFycm93SGVscGVyLnByb3RvdHlwZS5zZXRDb2xvciA9IGZ1bmN0aW9uICggY29sb3IgKSB7XG5cblx0dGhpcy5saW5lLm1hdGVyaWFsLmNvbG9yLmNvcHkoIGNvbG9yICk7XG5cdHRoaXMuY29uZS5tYXRlcmlhbC5jb2xvci5jb3B5KCBjb2xvciApO1xuXG59O1xuXG4vKipcbiAqIEBhdXRob3Igc3JvdWNoZXJheSAvIGh0dHA6Ly9zcm91Y2hlcmF5Lm9yZy9cbiAqIEBhdXRob3IgbXJkb29iIC8gaHR0cDovL21yZG9vYi5jb20vXG4gKi9cblxuZnVuY3Rpb24gQXhpc0hlbHBlciggc2l6ZSApIHtcblxuXHRzaXplID0gc2l6ZSB8fCAxO1xuXG5cdHZhciB2ZXJ0aWNlcyA9IFtcblx0XHQwLCAwLCAwLCAgc2l6ZSwgMCwgMCxcblx0XHQwLCAwLCAwLCAgMCwgc2l6ZSwgMCxcblx0XHQwLCAwLCAwLCAgMCwgMCwgc2l6ZVxuXHRdO1xuXG5cdHZhciBjb2xvcnMgPSBbXG5cdFx0MSwgMCwgMCwgIDEsIDAuNiwgMCxcblx0XHQwLCAxLCAwLCAgMC42LCAxLCAwLFxuXHRcdDAsIDAsIDEsICAwLCAwLjYsIDFcblx0XTtcblxuXHR2YXIgZ2VvbWV0cnkgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKTtcblx0Z2VvbWV0cnkuYWRkQXR0cmlidXRlKCAncG9zaXRpb24nLCBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggdmVydGljZXMsIDMgKSApO1xuXHRnZW9tZXRyeS5hZGRBdHRyaWJ1dGUoICdjb2xvcicsIG5ldyBGbG9hdDMyQnVmZmVyQXR0cmlidXRlKCBjb2xvcnMsIDMgKSApO1xuXG5cdHZhciBtYXRlcmlhbCA9IG5ldyBMaW5lQmFzaWNNYXRlcmlhbCggeyB2ZXJ0ZXhDb2xvcnM6IFZlcnRleENvbG9ycyB9ICk7XG5cblx0TGluZVNlZ21lbnRzLmNhbGwoIHRoaXMsIGdlb21ldHJ5LCBtYXRlcmlhbCApO1xuXG59XG5cbkF4aXNIZWxwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggTGluZVNlZ21lbnRzLnByb3RvdHlwZSApO1xuQXhpc0hlbHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBBeGlzSGVscGVyO1xuXG4vKipcbiAqIEBhdXRob3Igeno4NSBodHRwczovL2dpdGh1Yi5jb20veno4NVxuICpcbiAqIENlbnRyaXBldGFsIENhdG11bGxSb20gQ3VydmUgLSB3aGljaCBpcyB1c2VmdWwgZm9yIGF2b2lkaW5nXG4gKiBjdXNwcyBhbmQgc2VsZi1pbnRlcnNlY3Rpb25zIGluIG5vbi11bmlmb3JtIGNhdG11bGwgcm9tIGN1cnZlcy5cbiAqIGh0dHA6Ly93d3cuY2VteXVrc2VsLmNvbS9yZXNlYXJjaC9jYXRtdWxscm9tX3BhcmFtL2NhdG11bGxyb20ucGRmXG4gKlxuICogY3VydmUudHlwZSBhY2NlcHRzIGNlbnRyaXBldGFsKGRlZmF1bHQpLCBjaG9yZGFsIGFuZCBjYXRtdWxscm9tXG4gKiBjdXJ2ZS50ZW5zaW9uIGlzIHVzZWQgZm9yIGNhdG11bGxyb20gd2hpY2ggZGVmYXVsdHMgdG8gMC41XG4gKi9cblxuXG4vKlxuQmFzZWQgb24gYW4gb3B0aW1pemVkIGMrKyBzb2x1dGlvbiBpblxuIC0gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy85NDg5NzM2L2NhdG11bGwtcm9tLWN1cnZlLXdpdGgtbm8tY3VzcHMtYW5kLW5vLXNlbGYtaW50ZXJzZWN0aW9ucy9cbiAtIGh0dHA6Ly9pZGVvbmUuY29tL05vRWJWTVxuXG5UaGlzIEN1YmljUG9seSBjbGFzcyBjb3VsZCBiZSB1c2VkIGZvciByZXVzaW5nIHNvbWUgdmFyaWFibGVzIGFuZCBjYWxjdWxhdGlvbnMsXG5idXQgZm9yIHRocmVlLmpzIGN1cnZlIHVzZSwgaXQgY291bGQgYmUgcG9zc2libGUgaW5saW5lZCBhbmQgZmxhdHRlbiBpbnRvIGEgc2luZ2xlIGZ1bmN0aW9uIGNhbGxcbndoaWNoIGNhbiBiZSBwbGFjZWQgaW4gQ3VydmVVdGlscy5cbiovXG5cbmZ1bmN0aW9uIEN1YmljUG9seSgpIHtcblxuXHR2YXIgYzAgPSAwLCBjMSA9IDAsIGMyID0gMCwgYzMgPSAwO1xuXG5cdC8qXG5cdCAqIENvbXB1dGUgY29lZmZpY2llbnRzIGZvciBhIGN1YmljIHBvbHlub21pYWxcblx0ICogICBwKHMpID0gYzAgKyBjMSpzICsgYzIqc14yICsgYzMqc14zXG5cdCAqIHN1Y2ggdGhhdFxuXHQgKiAgIHAoMCkgPSB4MCwgcCgxKSA9IHgxXG5cdCAqICBhbmRcblx0ICogICBwJygwKSA9IHQwLCBwJygxKSA9IHQxLlxuXHQgKi9cblx0ZnVuY3Rpb24gaW5pdCggeDAsIHgxLCB0MCwgdDEgKSB7XG5cblx0XHRjMCA9IHgwO1xuXHRcdGMxID0gdDA7XG5cdFx0YzIgPSAtIDMgKiB4MCArIDMgKiB4MSAtIDIgKiB0MCAtIHQxO1xuXHRcdGMzID0gMiAqIHgwIC0gMiAqIHgxICsgdDAgKyB0MTtcblxuXHR9XG5cblx0cmV0dXJuIHtcblxuXHRcdGluaXRDYXRtdWxsUm9tOiBmdW5jdGlvbiAoIHgwLCB4MSwgeDIsIHgzLCB0ZW5zaW9uICkge1xuXG5cdFx0XHRpbml0KCB4MSwgeDIsIHRlbnNpb24gKiAoIHgyIC0geDAgKSwgdGVuc2lvbiAqICggeDMgLSB4MSApICk7XG5cblx0XHR9LFxuXG5cdFx0aW5pdE5vbnVuaWZvcm1DYXRtdWxsUm9tOiBmdW5jdGlvbiAoIHgwLCB4MSwgeDIsIHgzLCBkdDAsIGR0MSwgZHQyICkge1xuXG5cdFx0XHQvLyBjb21wdXRlIHRhbmdlbnRzIHdoZW4gcGFyYW1ldGVyaXplZCBpbiBbdDEsdDJdXG5cdFx0XHR2YXIgdDEgPSAoIHgxIC0geDAgKSAvIGR0MCAtICggeDIgLSB4MCApIC8gKCBkdDAgKyBkdDEgKSArICggeDIgLSB4MSApIC8gZHQxO1xuXHRcdFx0dmFyIHQyID0gKCB4MiAtIHgxICkgLyBkdDEgLSAoIHgzIC0geDEgKSAvICggZHQxICsgZHQyICkgKyAoIHgzIC0geDIgKSAvIGR0MjtcblxuXHRcdFx0Ly8gcmVzY2FsZSB0YW5nZW50cyBmb3IgcGFyYW1ldHJpemF0aW9uIGluIFswLDFdXG5cdFx0XHR0MSAqPSBkdDE7XG5cdFx0XHR0MiAqPSBkdDE7XG5cblx0XHRcdGluaXQoIHgxLCB4MiwgdDEsIHQyICk7XG5cblx0XHR9LFxuXG5cdFx0Y2FsYzogZnVuY3Rpb24gKCB0ICkge1xuXG5cdFx0XHR2YXIgdDIgPSB0ICogdDtcblx0XHRcdHZhciB0MyA9IHQyICogdDtcblx0XHRcdHJldHVybiBjMCArIGMxICogdCArIGMyICogdDIgKyBjMyAqIHQzO1xuXG5cdFx0fVxuXG5cdH07XG5cbn1cblxuLy9cblxudmFyIHRtcCA9IG5ldyBWZWN0b3IzKCk7XG52YXIgcHggPSBuZXcgQ3ViaWNQb2x5KCk7XG52YXIgcHkgPSBuZXcgQ3ViaWNQb2x5KCk7XG52YXIgcHogPSBuZXcgQ3ViaWNQb2x5KCk7XG5cbmZ1bmN0aW9uIENhdG11bGxSb21DdXJ2ZTMoIHAgLyogYXJyYXkgb2YgVmVjdG9yMyAqLyApIHtcblxuXHRDdXJ2ZS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5wb2ludHMgPSBwIHx8IFtdO1xuXHR0aGlzLmNsb3NlZCA9IGZhbHNlO1xuXG59XG5cbkNhdG11bGxSb21DdXJ2ZTMucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQ3VydmUucHJvdG90eXBlICk7XG5DYXRtdWxsUm9tQ3VydmUzLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IENhdG11bGxSb21DdXJ2ZTM7XG5cbkNhdG11bGxSb21DdXJ2ZTMucHJvdG90eXBlLmdldFBvaW50ID0gZnVuY3Rpb24gKCB0ICkge1xuXG5cdHZhciBwb2ludHMgPSB0aGlzLnBvaW50cztcblx0dmFyIGwgPSBwb2ludHMubGVuZ3RoO1xuXG5cdGlmICggbCA8IDIgKSBjb25zb2xlLmxvZyggJ2R1aCwgeW91IG5lZWQgYXQgbGVhc3QgMiBwb2ludHMnICk7XG5cblx0dmFyIHBvaW50ID0gKCBsIC0gKCB0aGlzLmNsb3NlZCA/IDAgOiAxICkgKSAqIHQ7XG5cdHZhciBpbnRQb2ludCA9IE1hdGguZmxvb3IoIHBvaW50ICk7XG5cdHZhciB3ZWlnaHQgPSBwb2ludCAtIGludFBvaW50O1xuXG5cdGlmICggdGhpcy5jbG9zZWQgKSB7XG5cblx0XHRpbnRQb2ludCArPSBpbnRQb2ludCA+IDAgPyAwIDogKCBNYXRoLmZsb29yKCBNYXRoLmFicyggaW50UG9pbnQgKSAvIHBvaW50cy5sZW5ndGggKSArIDEgKSAqIHBvaW50cy5sZW5ndGg7XG5cblx0fSBlbHNlIGlmICggd2VpZ2h0ID09PSAwICYmIGludFBvaW50ID09PSBsIC0gMSApIHtcblxuXHRcdGludFBvaW50ID0gbCAtIDI7XG5cdFx0d2VpZ2h0ID0gMTtcblxuXHR9XG5cblx0dmFyIHAwLCBwMSwgcDIsIHAzOyAvLyA0IHBvaW50c1xuXG5cdGlmICggdGhpcy5jbG9zZWQgfHwgaW50UG9pbnQgPiAwICkge1xuXG5cdFx0cDAgPSBwb2ludHNbICggaW50UG9pbnQgLSAxICkgJSBsIF07XG5cblx0fSBlbHNlIHtcblxuXHRcdC8vIGV4dHJhcG9sYXRlIGZpcnN0IHBvaW50XG5cdFx0dG1wLnN1YlZlY3RvcnMoIHBvaW50c1sgMCBdLCBwb2ludHNbIDEgXSApLmFkZCggcG9pbnRzWyAwIF0gKTtcblx0XHRwMCA9IHRtcDtcblxuXHR9XG5cblx0cDEgPSBwb2ludHNbIGludFBvaW50ICUgbCBdO1xuXHRwMiA9IHBvaW50c1sgKCBpbnRQb2ludCArIDEgKSAlIGwgXTtcblxuXHRpZiAoIHRoaXMuY2xvc2VkIHx8IGludFBvaW50ICsgMiA8IGwgKSB7XG5cblx0XHRwMyA9IHBvaW50c1sgKCBpbnRQb2ludCArIDIgKSAlIGwgXTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gZXh0cmFwb2xhdGUgbGFzdCBwb2ludFxuXHRcdHRtcC5zdWJWZWN0b3JzKCBwb2ludHNbIGwgLSAxIF0sIHBvaW50c1sgbCAtIDIgXSApLmFkZCggcG9pbnRzWyBsIC0gMSBdICk7XG5cdFx0cDMgPSB0bXA7XG5cblx0fVxuXG5cdGlmICggdGhpcy50eXBlID09PSB1bmRlZmluZWQgfHwgdGhpcy50eXBlID09PSAnY2VudHJpcGV0YWwnIHx8IHRoaXMudHlwZSA9PT0gJ2Nob3JkYWwnICkge1xuXG5cdFx0Ly8gaW5pdCBDZW50cmlwZXRhbCAvIENob3JkYWwgQ2F0bXVsbC1Sb21cblx0XHR2YXIgcG93ID0gdGhpcy50eXBlID09PSAnY2hvcmRhbCcgPyAwLjUgOiAwLjI1O1xuXHRcdHZhciBkdDAgPSBNYXRoLnBvdyggcDAuZGlzdGFuY2VUb1NxdWFyZWQoIHAxICksIHBvdyApO1xuXHRcdHZhciBkdDEgPSBNYXRoLnBvdyggcDEuZGlzdGFuY2VUb1NxdWFyZWQoIHAyICksIHBvdyApO1xuXHRcdHZhciBkdDIgPSBNYXRoLnBvdyggcDIuZGlzdGFuY2VUb1NxdWFyZWQoIHAzICksIHBvdyApO1xuXG5cdFx0Ly8gc2FmZXR5IGNoZWNrIGZvciByZXBlYXRlZCBwb2ludHNcblx0XHRpZiAoIGR0MSA8IDFlLTQgKSBkdDEgPSAxLjA7XG5cdFx0aWYgKCBkdDAgPCAxZS00ICkgZHQwID0gZHQxO1xuXHRcdGlmICggZHQyIDwgMWUtNCApIGR0MiA9IGR0MTtcblxuXHRcdHB4LmluaXROb251bmlmb3JtQ2F0bXVsbFJvbSggcDAueCwgcDEueCwgcDIueCwgcDMueCwgZHQwLCBkdDEsIGR0MiApO1xuXHRcdHB5LmluaXROb251bmlmb3JtQ2F0bXVsbFJvbSggcDAueSwgcDEueSwgcDIueSwgcDMueSwgZHQwLCBkdDEsIGR0MiApO1xuXHRcdHB6LmluaXROb251bmlmb3JtQ2F0bXVsbFJvbSggcDAueiwgcDEueiwgcDIueiwgcDMueiwgZHQwLCBkdDEsIGR0MiApO1xuXG5cdH0gZWxzZSBpZiAoIHRoaXMudHlwZSA9PT0gJ2NhdG11bGxyb20nICkge1xuXG5cdFx0dmFyIHRlbnNpb24gPSB0aGlzLnRlbnNpb24gIT09IHVuZGVmaW5lZCA/IHRoaXMudGVuc2lvbiA6IDAuNTtcblx0XHRweC5pbml0Q2F0bXVsbFJvbSggcDAueCwgcDEueCwgcDIueCwgcDMueCwgdGVuc2lvbiApO1xuXHRcdHB5LmluaXRDYXRtdWxsUm9tKCBwMC55LCBwMS55LCBwMi55LCBwMy55LCB0ZW5zaW9uICk7XG5cdFx0cHouaW5pdENhdG11bGxSb20oIHAwLnosIHAxLnosIHAyLnosIHAzLnosIHRlbnNpb24gKTtcblxuXHR9XG5cblx0cmV0dXJuIG5ldyBWZWN0b3IzKCBweC5jYWxjKCB3ZWlnaHQgKSwgcHkuY2FsYyggd2VpZ2h0ICksIHB6LmNhbGMoIHdlaWdodCApICk7XG5cbn07XG5cbmZ1bmN0aW9uIEN1YmljQmV6aWVyQ3VydmUzKCB2MCwgdjEsIHYyLCB2MyApIHtcblxuXHRDdXJ2ZS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy52MCA9IHYwO1xuXHR0aGlzLnYxID0gdjE7XG5cdHRoaXMudjIgPSB2Mjtcblx0dGhpcy52MyA9IHYzO1xuXG59XG5cbkN1YmljQmV6aWVyQ3VydmUzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuQ3ViaWNCZXppZXJDdXJ2ZTMucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ3ViaWNCZXppZXJDdXJ2ZTM7XG5cbkN1YmljQmV6aWVyQ3VydmUzLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uICggdCApIHtcblxuXHR2YXIgdjAgPSB0aGlzLnYwLCB2MSA9IHRoaXMudjEsIHYyID0gdGhpcy52MiwgdjMgPSB0aGlzLnYzO1xuXG5cdHJldHVybiBuZXcgVmVjdG9yMyhcblx0XHRDdWJpY0JlemllciggdCwgdjAueCwgdjEueCwgdjIueCwgdjMueCApLFxuXHRcdEN1YmljQmV6aWVyKCB0LCB2MC55LCB2MS55LCB2Mi55LCB2My55ICksXG5cdFx0Q3ViaWNCZXppZXIoIHQsIHYwLnosIHYxLnosIHYyLnosIHYzLnogKVxuXHQpO1xuXG59O1xuXG5mdW5jdGlvbiBRdWFkcmF0aWNCZXppZXJDdXJ2ZTMoIHYwLCB2MSwgdjIgKSB7XG5cblx0Q3VydmUuY2FsbCggdGhpcyApO1xuXG5cdHRoaXMudjAgPSB2MDtcblx0dGhpcy52MSA9IHYxO1xuXHR0aGlzLnYyID0gdjI7XG5cbn1cblxuUXVhZHJhdGljQmV6aWVyQ3VydmUzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuUXVhZHJhdGljQmV6aWVyQ3VydmUzLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFF1YWRyYXRpY0JlemllckN1cnZlMztcblxuUXVhZHJhdGljQmV6aWVyQ3VydmUzLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uICggdCApIHtcblxuXHR2YXIgdjAgPSB0aGlzLnYwLCB2MSA9IHRoaXMudjEsIHYyID0gdGhpcy52MjtcblxuXHRyZXR1cm4gbmV3IFZlY3RvcjMoXG5cdFx0UXVhZHJhdGljQmV6aWVyKCB0LCB2MC54LCB2MS54LCB2Mi54ICksXG5cdFx0UXVhZHJhdGljQmV6aWVyKCB0LCB2MC55LCB2MS55LCB2Mi55ICksXG5cdFx0UXVhZHJhdGljQmV6aWVyKCB0LCB2MC56LCB2MS56LCB2Mi56IClcblx0KTtcblxufTtcblxuZnVuY3Rpb24gTGluZUN1cnZlMyggdjEsIHYyICkge1xuXG5cdEN1cnZlLmNhbGwoIHRoaXMgKTtcblxuXHR0aGlzLnYxID0gdjE7XG5cdHRoaXMudjIgPSB2MjtcblxufVxuXG5MaW5lQ3VydmUzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIEN1cnZlLnByb3RvdHlwZSApO1xuTGluZUN1cnZlMy5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMaW5lQ3VydmUzO1xuXG5MaW5lQ3VydmUzLnByb3RvdHlwZS5nZXRQb2ludCA9IGZ1bmN0aW9uICggdCApIHtcblxuXHRpZiAoIHQgPT09IDEgKSB7XG5cblx0XHRyZXR1cm4gdGhpcy52Mi5jbG9uZSgpO1xuXG5cdH1cblxuXHR2YXIgdmVjdG9yID0gbmV3IFZlY3RvcjMoKTtcblxuXHR2ZWN0b3Iuc3ViVmVjdG9ycyggdGhpcy52MiwgdGhpcy52MSApOyAvLyBkaWZmXG5cdHZlY3Rvci5tdWx0aXBseVNjYWxhciggdCApO1xuXHR2ZWN0b3IuYWRkKCB0aGlzLnYxICk7XG5cblx0cmV0dXJuIHZlY3RvcjtcblxufTtcblxuZnVuY3Rpb24gQXJjQ3VydmUoIGFYLCBhWSwgYVJhZGl1cywgYVN0YXJ0QW5nbGUsIGFFbmRBbmdsZSwgYUNsb2Nrd2lzZSApIHtcblxuXHRFbGxpcHNlQ3VydmUuY2FsbCggdGhpcywgYVgsIGFZLCBhUmFkaXVzLCBhUmFkaXVzLCBhU3RhcnRBbmdsZSwgYUVuZEFuZ2xlLCBhQ2xvY2t3aXNlICk7XG5cbn1cblxuQXJjQ3VydmUucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggRWxsaXBzZUN1cnZlLnByb3RvdHlwZSApO1xuQXJjQ3VydmUucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQXJjQ3VydmU7XG5cbi8qKlxuICogQGF1dGhvciBhbHRlcmVkcSAvIGh0dHA6Ly9hbHRlcmVkcXVhbGlhLmNvbS9cbiAqL1xuXG52YXIgU2NlbmVVdGlscyA9IHtcblxuXHRjcmVhdGVNdWx0aU1hdGVyaWFsT2JqZWN0OiBmdW5jdGlvbiAoIGdlb21ldHJ5LCBtYXRlcmlhbHMgKSB7XG5cblx0XHR2YXIgZ3JvdXAgPSBuZXcgR3JvdXAoKTtcblxuXHRcdGZvciAoIHZhciBpID0gMCwgbCA9IG1hdGVyaWFscy5sZW5ndGg7IGkgPCBsOyBpICsrICkge1xuXG5cdFx0XHRncm91cC5hZGQoIG5ldyBNZXNoKCBnZW9tZXRyeSwgbWF0ZXJpYWxzWyBpIF0gKSApO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGdyb3VwO1xuXG5cdH0sXG5cblx0ZGV0YWNoOiBmdW5jdGlvbiAoIGNoaWxkLCBwYXJlbnQsIHNjZW5lICkge1xuXG5cdFx0Y2hpbGQuYXBwbHlNYXRyaXgoIHBhcmVudC5tYXRyaXhXb3JsZCApO1xuXHRcdHBhcmVudC5yZW1vdmUoIGNoaWxkICk7XG5cdFx0c2NlbmUuYWRkKCBjaGlsZCApO1xuXG5cdH0sXG5cblx0YXR0YWNoOiBmdW5jdGlvbiAoIGNoaWxkLCBzY2VuZSwgcGFyZW50ICkge1xuXG5cdFx0dmFyIG1hdHJpeFdvcmxkSW52ZXJzZSA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0bWF0cml4V29ybGRJbnZlcnNlLmdldEludmVyc2UoIHBhcmVudC5tYXRyaXhXb3JsZCApO1xuXHRcdGNoaWxkLmFwcGx5TWF0cml4KCBtYXRyaXhXb3JsZEludmVyc2UgKTtcblxuXHRcdHNjZW5lLnJlbW92ZSggY2hpbGQgKTtcblx0XHRwYXJlbnQuYWRkKCBjaGlsZCApO1xuXG5cdH1cblxufTtcblxuLyoqXG4gKiBAYXV0aG9yIG1yZG9vYiAvIGh0dHA6Ly9tcmRvb2IuY29tL1xuICovXG5cbmZ1bmN0aW9uIEZhY2U0KCBhLCBiLCBjLCBkLCBub3JtYWwsIGNvbG9yLCBtYXRlcmlhbEluZGV4ICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkZhY2U0IGhhcyBiZWVuIHJlbW92ZWQuIEEgVEhSRUUuRmFjZTMgd2lsbCBiZSBjcmVhdGVkIGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbmV3IEZhY2UzKCBhLCBiLCBjLCBub3JtYWwsIGNvbG9yLCBtYXRlcmlhbEluZGV4ICk7XG5cbn1cblxudmFyIExpbmVTdHJpcCA9IDA7XG5cbnZhciBMaW5lUGllY2VzID0gMTtcblxuZnVuY3Rpb24gTWVzaEZhY2VNYXRlcmlhbCggbWF0ZXJpYWxzICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLk1lc2hGYWNlTWF0ZXJpYWwgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIGFuIEFycmF5IGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbWF0ZXJpYWxzO1xuXG59XG5cbmZ1bmN0aW9uIE11bHRpTWF0ZXJpYWwoIG1hdGVyaWFscyApIHtcblxuXHRpZiAoIG1hdGVyaWFscyA9PT0gdW5kZWZpbmVkICkgbWF0ZXJpYWxzID0gW107XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuTXVsdGlNYXRlcmlhbCBoYXMgYmVlbiByZW1vdmVkLiBVc2UgYW4gQXJyYXkgaW5zdGVhZC4nICk7XG5cdG1hdGVyaWFscy5pc011bHRpTWF0ZXJpYWwgPSB0cnVlO1xuXHRtYXRlcmlhbHMubWF0ZXJpYWxzID0gbWF0ZXJpYWxzO1xuXHRtYXRlcmlhbHMuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRyZXR1cm4gbWF0ZXJpYWxzLnNsaWNlKCk7XG5cblx0fTtcblx0cmV0dXJuIG1hdGVyaWFscztcblxufVxuXG5mdW5jdGlvbiBQb2ludENsb3VkKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuUG9pbnRDbG91ZCBoYXMgYmVlbiByZW5hbWVkIHRvIFRIUkVFLlBvaW50cy4nICk7XG5cdHJldHVybiBuZXcgUG9pbnRzKCBnZW9tZXRyeSwgbWF0ZXJpYWwgKTtcblxufVxuXG5mdW5jdGlvbiBQYXJ0aWNsZSggbWF0ZXJpYWwgKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuUGFydGljbGUgaGFzIGJlZW4gcmVuYW1lZCB0byBUSFJFRS5TcHJpdGUuJyApO1xuXHRyZXR1cm4gbmV3IFNwcml0ZSggbWF0ZXJpYWwgKTtcblxufVxuXG5mdW5jdGlvbiBQYXJ0aWNsZVN5c3RlbSggZ2VvbWV0cnksIG1hdGVyaWFsICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlBhcnRpY2xlU3lzdGVtIGhhcyBiZWVuIHJlbmFtZWQgdG8gVEhSRUUuUG9pbnRzLicgKTtcblx0cmV0dXJuIG5ldyBQb2ludHMoIGdlb21ldHJ5LCBtYXRlcmlhbCApO1xuXG59XG5cbmZ1bmN0aW9uIFBvaW50Q2xvdWRNYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5Qb2ludENsb3VkTWF0ZXJpYWwgaGFzIGJlZW4gcmVuYW1lZCB0byBUSFJFRS5Qb2ludHNNYXRlcmlhbC4nICk7XG5cdHJldHVybiBuZXcgUG9pbnRzTWF0ZXJpYWwoIHBhcmFtZXRlcnMgKTtcblxufVxuXG5mdW5jdGlvbiBQYXJ0aWNsZUJhc2ljTWF0ZXJpYWwoIHBhcmFtZXRlcnMgKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuUGFydGljbGVCYXNpY01hdGVyaWFsIGhhcyBiZWVuIHJlbmFtZWQgdG8gVEhSRUUuUG9pbnRzTWF0ZXJpYWwuJyApO1xuXHRyZXR1cm4gbmV3IFBvaW50c01hdGVyaWFsKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuZnVuY3Rpb24gUGFydGljbGVTeXN0ZW1NYXRlcmlhbCggcGFyYW1ldGVycyApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5QYXJ0aWNsZVN5c3RlbU1hdGVyaWFsIGhhcyBiZWVuIHJlbmFtZWQgdG8gVEhSRUUuUG9pbnRzTWF0ZXJpYWwuJyApO1xuXHRyZXR1cm4gbmV3IFBvaW50c01hdGVyaWFsKCBwYXJhbWV0ZXJzICk7XG5cbn1cblxuZnVuY3Rpb24gVmVydGV4KCB4LCB5LCB6ICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlcnRleCBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuVmVjdG9yMyBpbnN0ZWFkLicgKTtcblx0cmV0dXJuIG5ldyBWZWN0b3IzKCB4LCB5LCB6ICk7XG5cbn1cblxuLy9cblxuZnVuY3Rpb24gRHluYW1pY0J1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkR5bmFtaWNCdWZmZXJBdHRyaWJ1dGUgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG5ldyBUSFJFRS5CdWZmZXJBdHRyaWJ1dGUoKS5zZXREeW5hbWljKCB0cnVlICkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgQnVmZmVyQXR0cmlidXRlKCBhcnJheSwgaXRlbVNpemUgKS5zZXREeW5hbWljKCB0cnVlICk7XG5cbn1cblxuZnVuY3Rpb24gSW50OEF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkludDhBdHRyaWJ1dGUgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG5ldyBUSFJFRS5JbnQ4QnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgSW50OEJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuZnVuY3Rpb24gVWludDhBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5VaW50OEF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLlVpbnQ4QnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgVWludDhCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApO1xuXG59XG5cbmZ1bmN0aW9uIFVpbnQ4Q2xhbXBlZEF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlVpbnQ4Q2xhbXBlZEF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLlVpbnQ4Q2xhbXBlZEJ1ZmZlckF0dHJpYnV0ZSgpIGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbmV3IFVpbnQ4Q2xhbXBlZEJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuZnVuY3Rpb24gSW50MTZBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5JbnQxNkF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLkludDE2QnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgSW50MTZCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApO1xuXG59XG5cbmZ1bmN0aW9uIFVpbnQxNkF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlVpbnQxNkF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLlVpbnQxNkJ1ZmZlckF0dHJpYnV0ZSgpIGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbmV3IFVpbnQxNkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuZnVuY3Rpb24gSW50MzJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5JbnQzMkF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLkludDMyQnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgSW50MzJCdWZmZXJBdHRyaWJ1dGUoIGFycmF5LCBpdGVtU2l6ZSApO1xuXG59XG5cbmZ1bmN0aW9uIFVpbnQzMkF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlVpbnQzMkF0dHJpYnV0ZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbmV3IFRIUkVFLlVpbnQzMkJ1ZmZlckF0dHJpYnV0ZSgpIGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbmV3IFVpbnQzMkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuZnVuY3Rpb24gRmxvYXQzMkF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkZsb2F0MzJBdHRyaWJ1dGUgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG5ldyBUSFJFRS5GbG9hdDMyQnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuZnVuY3Rpb24gRmxvYXQ2NEF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkZsb2F0NjRBdHRyaWJ1dGUgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG5ldyBUSFJFRS5GbG9hdDY0QnVmZmVyQXR0cmlidXRlKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgRmxvYXQ2NEJ1ZmZlckF0dHJpYnV0ZSggYXJyYXksIGl0ZW1TaXplICk7XG5cbn1cblxuLy9cblxuQ3VydmUuY3JlYXRlID0gZnVuY3Rpb24gKCBjb25zdHJ1Y3QsIGdldFBvaW50ICkge1xuXG5cdGNvbnNvbGUubG9nKCAnVEhSRUUuQ3VydmUuY3JlYXRlKCkgaGFzIGJlZW4gZGVwcmVjYXRlZCcgKTtcblxuXHRjb25zdHJ1Y3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggQ3VydmUucHJvdG90eXBlICk7XG5cdGNvbnN0cnVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjb25zdHJ1Y3Q7XG5cdGNvbnN0cnVjdC5wcm90b3R5cGUuZ2V0UG9pbnQgPSBnZXRQb2ludDtcblxuXHRyZXR1cm4gY29uc3RydWN0O1xuXG59O1xuXG4vL1xuXG5mdW5jdGlvbiBDbG9zZWRTcGxpbmVDdXJ2ZTMoIHBvaW50cyApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5DbG9zZWRTcGxpbmVDdXJ2ZTMgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIFRIUkVFLkNhdG11bGxSb21DdXJ2ZTMgaW5zdGVhZC4nICk7XG5cblx0Q2F0bXVsbFJvbUN1cnZlMy5jYWxsKCB0aGlzLCBwb2ludHMgKTtcblx0dGhpcy50eXBlID0gJ2NhdG11bGxyb20nO1xuXHR0aGlzLmNsb3NlZCA9IHRydWU7XG5cbn1cblxuQ2xvc2VkU3BsaW5lQ3VydmUzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIENhdG11bGxSb21DdXJ2ZTMucHJvdG90eXBlICk7XG5cbi8vXG5cbmZ1bmN0aW9uIFNwbGluZUN1cnZlMyggcG9pbnRzICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlNwbGluZUN1cnZlMyBoYXMgYmVlbiBkZXByZWNhdGVkLiBVc2UgVEhSRUUuQ2F0bXVsbFJvbUN1cnZlMyBpbnN0ZWFkLicgKTtcblxuXHRDYXRtdWxsUm9tQ3VydmUzLmNhbGwoIHRoaXMsIHBvaW50cyApO1xuXHR0aGlzLnR5cGUgPSAnY2F0bXVsbHJvbSc7XG5cbn1cblxuU3BsaW5lQ3VydmUzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIENhdG11bGxSb21DdXJ2ZTMucHJvdG90eXBlICk7XG5cbi8vXG5cbmZ1bmN0aW9uIFNwbGluZSggcG9pbnRzICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlNwbGluZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuQ2F0bXVsbFJvbUN1cnZlMyBpbnN0ZWFkLicgKTtcblxuXHRDYXRtdWxsUm9tQ3VydmUzLmNhbGwoIHRoaXMsIHBvaW50cyApO1xuXHR0aGlzLnR5cGUgPSAnY2F0bXVsbHJvbSc7XG5cbn1cblxuU3BsaW5lLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIENhdG11bGxSb21DdXJ2ZTMucHJvdG90eXBlICk7XG5cbk9iamVjdC5hc3NpZ24oIFNwbGluZS5wcm90b3R5cGUsIHtcblxuXHRpbml0RnJvbUFycmF5OiBmdW5jdGlvbiAoIGEgKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuU3BsaW5lOiAuaW5pdEZyb21BcnJheSgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdGdldENvbnRyb2xQb2ludHNBcnJheTogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5TcGxpbmU6IC5nZXRDb250cm9sUG9pbnRzQXJyYXkoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9LFxuXHRyZXBhcmFtZXRyaXplQnlBcmNMZW5ndGg6IGZ1bmN0aW9uICggc2FtcGxpbmdDb2VmICkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLlNwbGluZTogLnJlcGFyYW1ldHJpemVCeUFyY0xlbmd0aCgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH1cblxufSApO1xuXG4vL1xuZnVuY3Rpb24gQm91bmRpbmdCb3hIZWxwZXIoIG9iamVjdCwgY29sb3IgKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuQm91bmRpbmdCb3hIZWxwZXIgaGFzIGJlZW4gZGVwcmVjYXRlZC4gQ3JlYXRpbmcgYSBUSFJFRS5Cb3hIZWxwZXIgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgQm94SGVscGVyKCBvYmplY3QsIGNvbG9yICk7XG5cbn1cblxuZnVuY3Rpb24gRWRnZXNIZWxwZXIoIG9iamVjdCwgaGV4ICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkVkZ2VzSGVscGVyIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSBUSFJFRS5FZGdlc0dlb21ldHJ5IGluc3RlYWQuJyApO1xuXHRyZXR1cm4gbmV3IExpbmVTZWdtZW50cyggbmV3IEVkZ2VzR2VvbWV0cnkoIG9iamVjdC5nZW9tZXRyeSApLCBuZXcgTGluZUJhc2ljTWF0ZXJpYWwoIHsgY29sb3I6IGhleCAhPT0gdW5kZWZpbmVkID8gaGV4IDogMHhmZmZmZmYgfSApICk7XG5cbn1cblxuR3JpZEhlbHBlci5wcm90b3R5cGUuc2V0Q29sb3JzID0gZnVuY3Rpb24gKCkge1xuXG5cdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5HcmlkSGVscGVyOiBzZXRDb2xvcnMoKSBoYXMgYmVlbiBkZXByZWNhdGVkLCBwYXNzIHRoZW0gaW4gdGhlIGNvbnN0cnVjdG9yIGluc3RlYWQuJyApO1xuXG59O1xuXG5mdW5jdGlvbiBXaXJlZnJhbWVIZWxwZXIoIG9iamVjdCwgaGV4ICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLldpcmVmcmFtZUhlbHBlciBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuV2lyZWZyYW1lR2VvbWV0cnkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBuZXcgTGluZVNlZ21lbnRzKCBuZXcgV2lyZWZyYW1lR2VvbWV0cnkoIG9iamVjdC5nZW9tZXRyeSApLCBuZXcgTGluZUJhc2ljTWF0ZXJpYWwoIHsgY29sb3I6IGhleCAhPT0gdW5kZWZpbmVkID8gaGV4IDogMHhmZmZmZmYgfSApICk7XG5cbn1cblxuLy9cblxuZnVuY3Rpb24gWEhSTG9hZGVyKCBtYW5hZ2VyICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLlhIUkxvYWRlciBoYXMgYmVlbiByZW5hbWVkIHRvIFRIUkVFLkZpbGVMb2FkZXIuJyApO1xuXHRyZXR1cm4gbmV3IEZpbGVMb2FkZXIoIG1hbmFnZXIgKTtcblxufVxuXG5mdW5jdGlvbiBCaW5hcnlUZXh0dXJlTG9hZGVyKCBtYW5hZ2VyICkge1xuXG5cdGNvbnNvbGUud2FybiggJ1RIUkVFLkJpbmFyeVRleHR1cmVMb2FkZXIgaGFzIGJlZW4gcmVuYW1lZCB0byBUSFJFRS5EYXRhVGV4dHVyZUxvYWRlci4nICk7XG5cdHJldHVybiBuZXcgRGF0YVRleHR1cmVMb2FkZXIoIG1hbmFnZXIgKTtcblxufVxuXG4vL1xuXG5PYmplY3QuYXNzaWduKCBCb3gyLnByb3RvdHlwZSwge1xuXG5cdGNlbnRlcjogZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJveDI6IC5jZW50ZXIoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5nZXRDZW50ZXIoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0Q2VudGVyKCBvcHRpb25hbFRhcmdldCApO1xuXG5cdH0sXG5cdGVtcHR5OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Cb3gyOiAuZW1wdHkoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5pc0VtcHR5KCkuJyApO1xuXHRcdHJldHVybiB0aGlzLmlzRW1wdHkoKTtcblxuXHR9LFxuXHRpc0ludGVyc2VjdGlvbkJveDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Cb3gyOiAuaXNJbnRlcnNlY3Rpb25Cb3goKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5pbnRlcnNlY3RzQm94KCkuJyApO1xuXHRcdHJldHVybiB0aGlzLmludGVyc2VjdHNCb3goIGJveCApO1xuXG5cdH0sXG5cdHNpemU6IGZ1bmN0aW9uICggb3B0aW9uYWxUYXJnZXQgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Cb3gyOiAuc2l6ZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmdldFNpemUoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0U2l6ZSggb3B0aW9uYWxUYXJnZXQgKTtcblxuXHR9XG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIEJveDMucHJvdG90eXBlLCB7XG5cblx0Y2VudGVyOiBmdW5jdGlvbiAoIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQm94MzogLmNlbnRlcigpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmdldENlbnRlcigpLicgKTtcblx0XHRyZXR1cm4gdGhpcy5nZXRDZW50ZXIoIG9wdGlvbmFsVGFyZ2V0ICk7XG5cblx0fSxcblx0ZW1wdHk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJveDM6IC5lbXB0eSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmlzRW1wdHkoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuaXNFbXB0eSgpO1xuXG5cdH0sXG5cdGlzSW50ZXJzZWN0aW9uQm94OiBmdW5jdGlvbiAoIGJveCApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJveDM6IC5pc0ludGVyc2VjdGlvbkJveCgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmludGVyc2VjdHNCb3goKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuaW50ZXJzZWN0c0JveCggYm94ICk7XG5cblx0fSxcblx0aXNJbnRlcnNlY3Rpb25TcGhlcmU6IGZ1bmN0aW9uICggc3BoZXJlICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQm94MzogLmlzSW50ZXJzZWN0aW9uU3BoZXJlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuaW50ZXJzZWN0c1NwaGVyZSgpLicgKTtcblx0XHRyZXR1cm4gdGhpcy5pbnRlcnNlY3RzU3BoZXJlKCBzcGhlcmUgKTtcblxuXHR9LFxuXHRzaXplOiBmdW5jdGlvbiAoIG9wdGlvbmFsVGFyZ2V0ICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQm94MzogLnNpemUoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5nZXRTaXplKCkuJyApO1xuXHRcdHJldHVybiB0aGlzLmdldFNpemUoIG9wdGlvbmFsVGFyZ2V0ICk7XG5cblx0fVxufSApO1xuXG5MaW5lMy5wcm90b3R5cGUuY2VudGVyID0gZnVuY3Rpb24gKCBvcHRpb25hbFRhcmdldCApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5MaW5lMzogLmNlbnRlcigpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmdldENlbnRlcigpLicgKTtcblx0cmV0dXJuIHRoaXMuZ2V0Q2VudGVyKCBvcHRpb25hbFRhcmdldCApO1xuXG59O1xuXG5fTWF0aC5yYW5kb20xNiA9IGZ1bmN0aW9uICgpIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRoLnJhbmRvbTE2KCkgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIE1hdGgucmFuZG9tKCkgaW5zdGVhZC4nICk7XG5cdHJldHVybiBNYXRoLnJhbmRvbSgpO1xuXG59O1xuXG5PYmplY3QuYXNzaWduKCBNYXRyaXgzLnByb3RvdHlwZSwge1xuXG5cdGZsYXR0ZW5Ub0FycmF5T2Zmc2V0OiBmdW5jdGlvbiAoIGFycmF5LCBvZmZzZXQgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oIFwiVEhSRUUuTWF0cml4MzogLmZsYXR0ZW5Ub0FycmF5T2Zmc2V0KCkgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIC50b0FycmF5KCkgaW5zdGVhZC5cIiApO1xuXHRcdHJldHVybiB0aGlzLnRvQXJyYXkoIGFycmF5LCBvZmZzZXQgKTtcblxuXHR9LFxuXHRtdWx0aXBseVZlY3RvcjM6IGZ1bmN0aW9uICggdmVjdG9yICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0cml4MzogLm11bHRpcGx5VmVjdG9yMygpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSB2ZWN0b3IuYXBwbHlNYXRyaXgzKCBtYXRyaXggKSBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gdmVjdG9yLmFwcGx5TWF0cml4MyggdGhpcyApO1xuXG5cdH0sXG5cdG11bHRpcGx5VmVjdG9yM0FycmF5OiBmdW5jdGlvbiAoIGEgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRyaXgzOiAubXVsdGlwbHlWZWN0b3IzQXJyYXkoKSBoYXMgYmVlbiByZW5hbWVkLiBVc2UgbWF0cml4LmFwcGx5VG9WZWN0b3IzQXJyYXkoIGFycmF5ICkgaW5zdGVhZC4nICk7XG5cdFx0cmV0dXJuIHRoaXMuYXBwbHlUb1ZlY3RvcjNBcnJheSggYSApO1xuXG5cdH0sXG5cdGFwcGx5VG9CdWZmZXI6IGZ1bmN0aW9uKCBidWZmZXIsIG9mZnNldCwgbGVuZ3RoICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0cml4MzogLmFwcGx5VG9CdWZmZXIoKSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgbWF0cml4LmFwcGx5VG9CdWZmZXJBdHRyaWJ1dGUoIGF0dHJpYnV0ZSApIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiB0aGlzLmFwcGx5VG9CdWZmZXJBdHRyaWJ1dGUoIGJ1ZmZlciApO1xuXG5cdH0sXG5cdGFwcGx5VG9WZWN0b3IzQXJyYXk6IGZ1bmN0aW9uKCBhcnJheSwgb2Zmc2V0LCBsZW5ndGggKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuTWF0cml4MzogLmFwcGx5VG9WZWN0b3IzQXJyYXkoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggTWF0cml4NC5wcm90b3R5cGUsIHtcblxuXHRleHRyYWN0UG9zaXRpb246IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5leHRyYWN0UG9zaXRpb24oKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5jb3B5UG9zaXRpb24oKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuY29weVBvc2l0aW9uKCBtICk7XG5cblx0fSxcblx0ZmxhdHRlblRvQXJyYXlPZmZzZXQ6IGZ1bmN0aW9uICggYXJyYXksIG9mZnNldCApIHtcblxuXHRcdGNvbnNvbGUud2FybiggXCJUSFJFRS5NYXRyaXg0OiAuZmxhdHRlblRvQXJyYXlPZmZzZXQoKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBVc2UgLnRvQXJyYXkoKSBpbnN0ZWFkLlwiICk7XG5cdFx0cmV0dXJuIHRoaXMudG9BcnJheSggYXJyYXksIG9mZnNldCApO1xuXG5cdH0sXG5cdGdldFBvc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgdjE7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24gZ2V0UG9zaXRpb24oKSB7XG5cblx0XHRcdGlmICggdjEgPT09IHVuZGVmaW5lZCApIHYxID0gbmV3IFZlY3RvcjMoKTtcblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5nZXRQb3NpdGlvbigpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSBWZWN0b3IzLnNldEZyb21NYXRyaXhQb3NpdGlvbiggbWF0cml4ICkgaW5zdGVhZC4nICk7XG5cdFx0XHRyZXR1cm4gdjEuc2V0RnJvbU1hdHJpeENvbHVtbiggdGhpcywgMyApO1xuXG5cdFx0fTtcblxuXHR9KCksXG5cdHNldFJvdGF0aW9uRnJvbVF1YXRlcm5pb246IGZ1bmN0aW9uICggcSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5zZXRSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24oKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMubWFrZVJvdGF0aW9uRnJvbVF1YXRlcm5pb24oIHEgKTtcblxuXHR9LFxuXHRtdWx0aXBseVRvQXJyYXk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5tdWx0aXBseVRvQXJyYXkoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9LFxuXHRtdWx0aXBseVZlY3RvcjM6IGZ1bmN0aW9uICggdmVjdG9yICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0cml4NDogLm11bHRpcGx5VmVjdG9yMygpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSB2ZWN0b3IuYXBwbHlNYXRyaXg0KCBtYXRyaXggKSBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gdmVjdG9yLmFwcGx5TWF0cml4NCggdGhpcyApO1xuXG5cdH0sXG5cdG11bHRpcGx5VmVjdG9yNDogZnVuY3Rpb24gKCB2ZWN0b3IgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRyaXg0OiAubXVsdGlwbHlWZWN0b3I0KCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIHZlY3Rvci5hcHBseU1hdHJpeDQoIG1hdHJpeCApIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiB2ZWN0b3IuYXBwbHlNYXRyaXg0KCB0aGlzICk7XG5cblx0fSxcblx0bXVsdGlwbHlWZWN0b3IzQXJyYXk6IGZ1bmN0aW9uICggYSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5tdWx0aXBseVZlY3RvcjNBcnJheSgpIGhhcyBiZWVuIHJlbmFtZWQuIFVzZSBtYXRyaXguYXBwbHlUb1ZlY3RvcjNBcnJheSggYXJyYXkgKSBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gdGhpcy5hcHBseVRvVmVjdG9yM0FycmF5KCBhICk7XG5cblx0fSxcblx0cm90YXRlQXhpczogZnVuY3Rpb24gKCB2ICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0cml4NDogLnJvdGF0ZUF4aXMoKSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVmVjdG9yMy50cmFuc2Zvcm1EaXJlY3Rpb24oIG1hdHJpeCApIGluc3RlYWQuJyApO1xuXHRcdHYudHJhbnNmb3JtRGlyZWN0aW9uKCB0aGlzICk7XG5cblx0fSxcblx0Y3Jvc3NWZWN0b3I6IGZ1bmN0aW9uICggdmVjdG9yICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0cml4NDogLmNyb3NzVmVjdG9yKCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIHZlY3Rvci5hcHBseU1hdHJpeDQoIG1hdHJpeCApIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiB2ZWN0b3IuYXBwbHlNYXRyaXg0KCB0aGlzICk7XG5cblx0fSxcblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuTWF0cml4NDogLnRyYW5zbGF0ZSgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdHJvdGF0ZVg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5NYXRyaXg0OiAucm90YXRlWCgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdHJvdGF0ZVk6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5NYXRyaXg0OiAucm90YXRlWSgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdHJvdGF0ZVo6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5NYXRyaXg0OiAucm90YXRlWigpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdHJvdGF0ZUJ5QXhpczogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLk1hdHJpeDQ6IC5yb3RhdGVCeUF4aXMoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9LFxuXHRhcHBseVRvQnVmZmVyOiBmdW5jdGlvbiggYnVmZmVyLCBvZmZzZXQsIGxlbmd0aCApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5hcHBseVRvQnVmZmVyKCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG1hdHJpeC5hcHBseVRvQnVmZmVyQXR0cmlidXRlKCBhdHRyaWJ1dGUgKSBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gdGhpcy5hcHBseVRvQnVmZmVyQXR0cmlidXRlKCBidWZmZXIgKTtcblxuXHR9LFxuXHRhcHBseVRvVmVjdG9yM0FycmF5OiBmdW5jdGlvbiggYXJyYXksIG9mZnNldCwgbGVuZ3RoICkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLk1hdHJpeDQ6IC5hcHBseVRvVmVjdG9yM0FycmF5KCkgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0fSxcblx0bWFrZUZydXN0dW06IGZ1bmN0aW9uKCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIG5lYXIsIGZhciApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1hdHJpeDQ6IC5tYWtlRnJ1c3R1bSgpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSAubWFrZVBlcnNwZWN0aXZlKCBsZWZ0LCByaWdodCwgdG9wLCBib3R0b20sIG5lYXIsIGZhciApIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiB0aGlzLm1ha2VQZXJzcGVjdGl2ZSggbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tLCBuZWFyLCBmYXIgKTtcblxuXHR9XG5cbn0gKTtcblxuUGxhbmUucHJvdG90eXBlLmlzSW50ZXJzZWN0aW9uTGluZSA9IGZ1bmN0aW9uICggbGluZSApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5QbGFuZTogLmlzSW50ZXJzZWN0aW9uTGluZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmludGVyc2VjdHNMaW5lKCkuJyApO1xuXHRyZXR1cm4gdGhpcy5pbnRlcnNlY3RzTGluZSggbGluZSApO1xuXG59O1xuXG5RdWF0ZXJuaW9uLnByb3RvdHlwZS5tdWx0aXBseVZlY3RvcjMgPSBmdW5jdGlvbiAoIHZlY3RvciApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5RdWF0ZXJuaW9uOiAubXVsdGlwbHlWZWN0b3IzKCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIGlzIG5vdyB2ZWN0b3IuYXBwbHlRdWF0ZXJuaW9uKCBxdWF0ZXJuaW9uICkgaW5zdGVhZC4nICk7XG5cdHJldHVybiB2ZWN0b3IuYXBwbHlRdWF0ZXJuaW9uKCB0aGlzICk7XG5cbn07XG5cbk9iamVjdC5hc3NpZ24oIFJheS5wcm90b3R5cGUsIHtcblxuXHRpc0ludGVyc2VjdGlvbkJveDogZnVuY3Rpb24gKCBib3ggKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5SYXk6IC5pc0ludGVyc2VjdGlvbkJveCgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmludGVyc2VjdHNCb3goKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuaW50ZXJzZWN0c0JveCggYm94ICk7XG5cblx0fSxcblx0aXNJbnRlcnNlY3Rpb25QbGFuZTogZnVuY3Rpb24gKCBwbGFuZSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlJheTogLmlzSW50ZXJzZWN0aW9uUGxhbmUoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5pbnRlcnNlY3RzUGxhbmUoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuaW50ZXJzZWN0c1BsYW5lKCBwbGFuZSApO1xuXG5cdH0sXG5cdGlzSW50ZXJzZWN0aW9uU3BoZXJlOiBmdW5jdGlvbiAoIHNwaGVyZSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlJheTogLmlzSW50ZXJzZWN0aW9uU3BoZXJlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuaW50ZXJzZWN0c1NwaGVyZSgpLicgKTtcblx0XHRyZXR1cm4gdGhpcy5pbnRlcnNlY3RzU3BoZXJlKCBzcGhlcmUgKTtcblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggU2hhcGUucHJvdG90eXBlLCB7XG5cblx0ZXh0cnVkZTogZnVuY3Rpb24gKCBvcHRpb25zICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuU2hhcGU6IC5leHRydWRlKCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIEV4dHJ1ZGVHZW9tZXRyeSgpIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiBuZXcgRXh0cnVkZUdlb21ldHJ5KCB0aGlzLCBvcHRpb25zICk7XG5cblx0fSxcblx0bWFrZUdlb21ldHJ5OiBmdW5jdGlvbiAoIG9wdGlvbnMgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5TaGFwZTogLm1ha2VHZW9tZXRyeSgpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSBTaGFwZUdlb21ldHJ5KCkgaW5zdGVhZC4nICk7XG5cdFx0cmV0dXJuIG5ldyBTaGFwZUdlb21ldHJ5KCB0aGlzLCBvcHRpb25zICk7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5hc3NpZ24oIFZlY3RvcjIucHJvdG90eXBlLCB7XG5cblx0ZnJvbUF0dHJpYnV0ZTogZnVuY3Rpb24gKCBhdHRyaWJ1dGUsIGluZGV4LCBvZmZzZXQgKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuVmVjdG9yMjogLmZyb21BdHRyaWJ1dGUoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5mcm9tQnVmZmVyQXR0cmlidXRlKCkuJyApO1xuXHRcdHJldHVybiB0aGlzLmZyb21CdWZmZXJBdHRyaWJ1dGUoIGF0dHJpYnV0ZSwgaW5kZXgsIG9mZnNldCApO1xuXG5cdH1cblxufSApO1xuXG5PYmplY3QuYXNzaWduKCBWZWN0b3IzLnByb3RvdHlwZSwge1xuXG5cdHNldEV1bGVyRnJvbVJvdGF0aW9uTWF0cml4OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLmVycm9yKCAnVEhSRUUuVmVjdG9yMzogLnNldEV1bGVyRnJvbVJvdGF0aW9uTWF0cml4KCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIEV1bGVyLnNldEZyb21Sb3RhdGlvbk1hdHJpeCgpIGluc3RlYWQuJyApO1xuXG5cdH0sXG5cdHNldEV1bGVyRnJvbVF1YXRlcm5pb246IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5WZWN0b3IzOiAuc2V0RXVsZXJGcm9tUXVhdGVybmlvbigpIGhhcyBiZWVuIHJlbW92ZWQuIFVzZSBFdWxlci5zZXRGcm9tUXVhdGVybmlvbigpIGluc3RlYWQuJyApO1xuXG5cdH0sXG5cdGdldFBvc2l0aW9uRnJvbU1hdHJpeDogZnVuY3Rpb24gKCBtICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVmVjdG9yMzogLmdldFBvc2l0aW9uRnJvbU1hdHJpeCgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLnNldEZyb21NYXRyaXhQb3NpdGlvbigpLicgKTtcblx0XHRyZXR1cm4gdGhpcy5zZXRGcm9tTWF0cml4UG9zaXRpb24oIG0gKTtcblxuXHR9LFxuXHRnZXRTY2FsZUZyb21NYXRyaXg6IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjM6IC5nZXRTY2FsZUZyb21NYXRyaXgoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5zZXRGcm9tTWF0cml4U2NhbGUoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuc2V0RnJvbU1hdHJpeFNjYWxlKCBtICk7XG5cblx0fSxcblx0Z2V0Q29sdW1uRnJvbU1hdHJpeDogZnVuY3Rpb24gKCBpbmRleCwgbWF0cml4ICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVmVjdG9yMzogLmdldENvbHVtbkZyb21NYXRyaXgoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5zZXRGcm9tTWF0cml4Q29sdW1uKCkuJyApO1xuXHRcdHJldHVybiB0aGlzLnNldEZyb21NYXRyaXhDb2x1bW4oIG1hdHJpeCwgaW5kZXggKTtcblxuXHR9LFxuXHRhcHBseVByb2plY3Rpb246IGZ1bmN0aW9uICggbSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlZlY3RvcjM6IC5hcHBseVByb2plY3Rpb24oKSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgLmFwcGx5TWF0cml4NCggbSApIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiB0aGlzLmFwcGx5TWF0cml4NCggbSApO1xuXG5cdH0sXG5cdGZyb21BdHRyaWJ1dGU6IGZ1bmN0aW9uICggYXR0cmlidXRlLCBpbmRleCwgb2Zmc2V0ICkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLlZlY3RvcjM6IC5mcm9tQXR0cmlidXRlKCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuZnJvbUJ1ZmZlckF0dHJpYnV0ZSgpLicgKTtcblx0XHRyZXR1cm4gdGhpcy5mcm9tQnVmZmVyQXR0cmlidXRlKCBhdHRyaWJ1dGUsIGluZGV4LCBvZmZzZXQgKTtcblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggVmVjdG9yNC5wcm90b3R5cGUsIHtcblxuXHRmcm9tQXR0cmlidXRlOiBmdW5jdGlvbiAoIGF0dHJpYnV0ZSwgaW5kZXgsIG9mZnNldCApIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5WZWN0b3I0OiAuZnJvbUF0dHJpYnV0ZSgpIGhhcyBiZWVuIHJlbmFtZWQgdG8gLmZyb21CdWZmZXJBdHRyaWJ1dGUoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZnJvbUJ1ZmZlckF0dHJpYnV0ZSggYXR0cmlidXRlLCBpbmRleCwgb2Zmc2V0ICk7XG5cblx0fVxuXG59ICk7XG5cbi8vXG5cbkdlb21ldHJ5LnByb3RvdHlwZS5jb21wdXRlVGFuZ2VudHMgPSBmdW5jdGlvbiAoKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuR2VvbWV0cnk6IC5jb21wdXRlVGFuZ2VudHMoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxufTtcblxuT2JqZWN0LmFzc2lnbiggT2JqZWN0M0QucHJvdG90eXBlLCB7XG5cblx0Z2V0Q2hpbGRCeU5hbWU6IGZ1bmN0aW9uICggbmFtZSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdDNEOiAuZ2V0Q2hpbGRCeU5hbWUoKSBoYXMgYmVlbiByZW5hbWVkIHRvIC5nZXRPYmplY3RCeU5hbWUoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0T2JqZWN0QnlOYW1lKCBuYW1lICk7XG5cblx0fSxcblx0cmVuZGVyRGVwdGg6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdDNEOiAucmVuZGVyRGVwdGggaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIC5yZW5kZXJPcmRlciwgaW5zdGVhZC4nICk7XG5cblx0fSxcblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoIGRpc3RhbmNlLCBheGlzICkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuT2JqZWN0M0Q6IC50cmFuc2xhdGUoKSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgLnRyYW5zbGF0ZU9uQXhpcyggYXhpcywgZGlzdGFuY2UgKSBpbnN0ZWFkLicgKTtcblx0XHRyZXR1cm4gdGhpcy50cmFuc2xhdGVPbkF4aXMoIGF4aXMsIGRpc3RhbmNlICk7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBPYmplY3QzRC5wcm90b3R5cGUsIHtcblxuXHRldWxlck9yZGVyOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdDNEOiAuZXVsZXJPcmRlciBpcyBub3cgLnJvdGF0aW9uLm9yZGVyLicgKTtcblx0XHRcdHJldHVybiB0aGlzLnJvdGF0aW9uLm9yZGVyO1xuXG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk9iamVjdDNEOiAuZXVsZXJPcmRlciBpcyBub3cgLnJvdGF0aW9uLm9yZGVyLicgKTtcblx0XHRcdHRoaXMucm90YXRpb24ub3JkZXIgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0dXNlUXVhdGVybmlvbjoge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3QzRDogLnVzZVF1YXRlcm5pb24gaGFzIGJlZW4gcmVtb3ZlZC4gVGhlIGxpYnJhcnkgbm93IHVzZXMgcXVhdGVybmlvbnMgYnkgZGVmYXVsdC4nICk7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5PYmplY3QzRDogLnVzZVF1YXRlcm5pb24gaGFzIGJlZW4gcmVtb3ZlZC4gVGhlIGxpYnJhcnkgbm93IHVzZXMgcXVhdGVybmlvbnMgYnkgZGVmYXVsdC4nICk7XG5cblx0XHR9XG5cdH1cblxufSApO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggTE9ELnByb3RvdHlwZSwge1xuXG5cdG9iamVjdHM6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTE9EOiAub2JqZWN0cyBoYXMgYmVlbiByZW5hbWVkIHRvIC5sZXZlbHMuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMubGV2ZWxzO1xuXG5cdFx0fVxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KCBTa2VsZXRvbi5wcm90b3R5cGUsICd1c2VWZXJ0ZXhUZXh0dXJlJywge1xuXG5cdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuU2tlbGV0b246IHVzZVZlcnRleFRleHR1cmUgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0fSxcblx0c2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Ta2VsZXRvbjogdXNlVmVydGV4VGV4dHVyZSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KCBDdXJ2ZS5wcm90b3R5cGUsICdfX2FyY0xlbmd0aERpdmlzaW9ucycsIHtcblxuXHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkN1cnZlOiAuX19hcmNMZW5ndGhEaXZpc2lvbnMgaXMgbm93IC5hcmNMZW5ndGhEaXZpc2lvbnMuJyApO1xuXHRcdHJldHVybiB0aGlzLmFyY0xlbmd0aERpdmlzaW9ucztcblxuXHR9LFxuXHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5DdXJ2ZTogLl9fYXJjTGVuZ3RoRGl2aXNpb25zIGlzIG5vdyAuYXJjTGVuZ3RoRGl2aXNpb25zLicgKTtcblx0XHR0aGlzLmFyY0xlbmd0aERpdmlzaW9ucyA9IHZhbHVlO1xuXG5cdH1cblxufSApO1xuXG4vL1xuXG5QZXJzcGVjdGl2ZUNhbWVyYS5wcm90b3R5cGUuc2V0TGVucyA9IGZ1bmN0aW9uICggZm9jYWxMZW5ndGgsIGZpbG1HYXVnZSApIHtcblxuXHRjb25zb2xlLndhcm4oIFwiVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEuc2V0TGVucyBpcyBkZXByZWNhdGVkLiBcIiArXG5cdFx0XHRcIlVzZSAuc2V0Rm9jYWxMZW5ndGggYW5kIC5maWxtR2F1Z2UgZm9yIGEgcGhvdG9ncmFwaGljIHNldHVwLlwiICk7XG5cblx0aWYgKCBmaWxtR2F1Z2UgIT09IHVuZGVmaW5lZCApIHRoaXMuZmlsbUdhdWdlID0gZmlsbUdhdWdlO1xuXHR0aGlzLnNldEZvY2FsTGVuZ3RoKCBmb2NhbExlbmd0aCApO1xuXG59O1xuXG4vL1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggTGlnaHQucHJvdG90eXBlLCB7XG5cdG9ubHlTaGFkb3c6IHtcblx0XHRzZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTGlnaHQ6IC5vbmx5U2hhZG93IGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dDYW1lcmFGb3Y6IHtcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkxpZ2h0OiAuc2hhZG93Q2FtZXJhRm92IGlzIG5vdyAuc2hhZG93LmNhbWVyYS5mb3YuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuY2FtZXJhLmZvdiA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dDYW1lcmFMZWZ0OiB7XG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd0NhbWVyYUxlZnQgaXMgbm93IC5zaGFkb3cuY2FtZXJhLmxlZnQuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuY2FtZXJhLmxlZnQgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0c2hhZG93Q2FtZXJhUmlnaHQ6IHtcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkxpZ2h0OiAuc2hhZG93Q2FtZXJhUmlnaHQgaXMgbm93IC5zaGFkb3cuY2FtZXJhLnJpZ2h0LicgKTtcblx0XHRcdHRoaXMuc2hhZG93LmNhbWVyYS5yaWdodCA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dDYW1lcmFUb3A6IHtcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkxpZ2h0OiAuc2hhZG93Q2FtZXJhVG9wIGlzIG5vdyAuc2hhZG93LmNhbWVyYS50b3AuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuY2FtZXJhLnRvcCA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dDYW1lcmFCb3R0b206IHtcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkxpZ2h0OiAuc2hhZG93Q2FtZXJhQm90dG9tIGlzIG5vdyAuc2hhZG93LmNhbWVyYS5ib3R0b20uJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuY2FtZXJhLmJvdHRvbSA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dDYW1lcmFOZWFyOiB7XG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd0NhbWVyYU5lYXIgaXMgbm93IC5zaGFkb3cuY2FtZXJhLm5lYXIuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuY2FtZXJhLm5lYXIgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0c2hhZG93Q2FtZXJhRmFyOiB7XG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd0NhbWVyYUZhciBpcyBub3cgLnNoYWRvdy5jYW1lcmEuZmFyLicgKTtcblx0XHRcdHRoaXMuc2hhZG93LmNhbWVyYS5mYXIgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0c2hhZG93Q2FtZXJhVmlzaWJsZToge1xuXHRcdHNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd0NhbWVyYVZpc2libGUgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG5ldyBUSFJFRS5DYW1lcmFIZWxwZXIoIGxpZ2h0LnNoYWRvdy5jYW1lcmEgKSBpbnN0ZWFkLicgKTtcblxuXHRcdH1cblx0fSxcblx0c2hhZG93Qmlhczoge1xuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTGlnaHQ6IC5zaGFkb3dCaWFzIGlzIG5vdyAuc2hhZG93LmJpYXMuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3cuYmlhcyA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dEYXJrbmVzczoge1xuXHRcdHNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd0RhcmtuZXNzIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdFx0fVxuXHR9LFxuXHRzaGFkb3dNYXBXaWR0aDoge1xuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTGlnaHQ6IC5zaGFkb3dNYXBXaWR0aCBpcyBub3cgLnNoYWRvdy5tYXBTaXplLndpZHRoLicgKTtcblx0XHRcdHRoaXMuc2hhZG93Lm1hcFNpemUud2lkdGggPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0c2hhZG93TWFwSGVpZ2h0OiB7XG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5MaWdodDogLnNoYWRvd01hcEhlaWdodCBpcyBub3cgLnNoYWRvdy5tYXBTaXplLmhlaWdodC4nICk7XG5cdFx0XHR0aGlzLnNoYWRvdy5tYXBTaXplLmhlaWdodCA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBCdWZmZXJBdHRyaWJ1dGUucHJvdG90eXBlLCB7XG5cblx0bGVuZ3RoOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJ1ZmZlckF0dHJpYnV0ZTogLmxlbmd0aCBoYXMgYmVlbiBkZXByZWNhdGVkLiBVc2UgLmNvdW50IGluc3RlYWQuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMuYXJyYXkubGVuZ3RoO1xuXG5cdFx0fVxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmFzc2lnbiggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLCB7XG5cblx0YWRkSW5kZXg6IGZ1bmN0aW9uICggaW5kZXggKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmFkZEluZGV4KCkgaGFzIGJlZW4gcmVuYW1lZCB0byAuc2V0SW5kZXgoKS4nICk7XG5cdFx0dGhpcy5zZXRJbmRleCggaW5kZXggKTtcblxuXHR9LFxuXHRhZGREcmF3Q2FsbDogZnVuY3Rpb24gKCBzdGFydCwgY291bnQsIGluZGV4T2Zmc2V0ICkge1xuXG5cdFx0aWYgKCBpbmRleE9mZnNldCAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmFkZERyYXdDYWxsKCkgbm8gbG9uZ2VyIHN1cHBvcnRzIGluZGV4T2Zmc2V0LicgKTtcblxuXHRcdH1cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmFkZERyYXdDYWxsKCkgaXMgbm93IC5hZGRHcm91cCgpLicgKTtcblx0XHR0aGlzLmFkZEdyb3VwKCBzdGFydCwgY291bnQgKTtcblxuXHR9LFxuXHRjbGVhckRyYXdDYWxsczogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyR2VvbWV0cnk6IC5jbGVhckRyYXdDYWxscygpIGlzIG5vdyAuY2xlYXJHcm91cHMoKS4nICk7XG5cdFx0dGhpcy5jbGVhckdyb3VwcygpO1xuXG5cdH0sXG5cdGNvbXB1dGVUYW5nZW50czogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyR2VvbWV0cnk6IC5jb21wdXRlVGFuZ2VudHMoKSBoYXMgYmVlbiByZW1vdmVkLicgKTtcblxuXHR9LFxuXHRjb21wdXRlT2Zmc2V0czogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuQnVmZmVyR2VvbWV0cnk6IC5jb21wdXRlT2Zmc2V0cygpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH1cblxufSApO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggQnVmZmVyR2VvbWV0cnkucHJvdG90eXBlLCB7XG5cblx0ZHJhd2NhbGxzOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5CdWZmZXJHZW9tZXRyeTogLmRyYXdjYWxscyBoYXMgYmVlbiByZW5hbWVkIHRvIC5ncm91cHMuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMuZ3JvdXBzO1xuXG5cdFx0fVxuXHR9LFxuXHRvZmZzZXRzOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkJ1ZmZlckdlb21ldHJ5OiAub2Zmc2V0cyBoYXMgYmVlbiByZW5hbWVkIHRvIC5ncm91cHMuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMuZ3JvdXBzO1xuXG5cdFx0fVxuXHR9XG5cbn0gKTtcblxuLy9cblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIFVuaWZvcm0ucHJvdG90eXBlLCB7XG5cblx0ZHluYW1pYzoge1xuXHRcdHNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Vbmlmb3JtOiAuZHluYW1pYyBoYXMgYmVlbiByZW1vdmVkLiBVc2Ugb2JqZWN0Lm9uQmVmb3JlUmVuZGVyKCkgaW5zdGVhZC4nICk7XG5cblx0XHR9XG5cdH0sXG5cdG9uVXBkYXRlOiB7XG5cdFx0dmFsdWU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuVW5pZm9ybTogLm9uVXBkYXRlKCkgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIG9iamVjdC5vbkJlZm9yZVJlbmRlcigpIGluc3RlYWQuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHR9XG5cdH1cblxufSApO1xuXG4vL1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggTWF0ZXJpYWwucHJvdG90eXBlLCB7XG5cblx0d3JhcEFyb3VuZDoge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRlcmlhbDogLndyYXBBcm91bmQgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5NYXRlcmlhbDogLndyYXBBcm91bmQgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0XHR9XG5cdH0sXG5cdHdyYXBSR0I6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWF0ZXJpYWw6IC53cmFwUkdCIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXHRcdFx0cmV0dXJuIG5ldyBDb2xvcigpO1xuXG5cdFx0fVxuXHR9XG5cbn0gKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoIE1lc2hQaG9uZ01hdGVyaWFsLnByb3RvdHlwZSwge1xuXG5cdG1ldGFsOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLk1lc2hQaG9uZ01hdGVyaWFsOiAubWV0YWwgaGFzIGJlZW4gcmVtb3ZlZC4gVXNlIFRIUkVFLk1lc2hTdGFuZGFyZE1hdGVyaWFsIGluc3RlYWQuJyApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuTWVzaFBob25nTWF0ZXJpYWw6IC5tZXRhbCBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuTWVzaFN0YW5kYXJkTWF0ZXJpYWwgaW5zdGVhZCcgKTtcblxuXHRcdH1cblx0fVxuXG59ICk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBTaGFkZXJNYXRlcmlhbC5wcm90b3R5cGUsIHtcblxuXHRkZXJpdmF0aXZlczoge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5TaGFkZXJNYXRlcmlhbDogLmRlcml2YXRpdmVzIGhhcyBiZWVuIG1vdmVkIHRvIC5leHRlbnNpb25zLmRlcml2YXRpdmVzLicgKTtcblx0XHRcdHJldHVybiB0aGlzLmV4dGVuc2lvbnMuZGVyaXZhdGl2ZXM7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuIFNoYWRlck1hdGVyaWFsOiAuZGVyaXZhdGl2ZXMgaGFzIGJlZW4gbW92ZWQgdG8gLmV4dGVuc2lvbnMuZGVyaXZhdGl2ZXMuJyApO1xuXHRcdFx0dGhpcy5leHRlbnNpb25zLmRlcml2YXRpdmVzID0gdmFsdWU7XG5cblx0XHR9XG5cdH1cblxufSApO1xuXG4vL1xuXG5PYmplY3QuYXNzaWduKCBXZWJHTFJlbmRlcmVyLnByb3RvdHlwZSwge1xuXG5cdGdldEN1cnJlbnRSZW5kZXJUYXJnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5nZXRDdXJyZW50UmVuZGVyVGFyZ2V0KCkgaXMgbm93IC5nZXRSZW5kZXJUYXJnZXQoKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UmVuZGVyVGFyZ2V0KCk7XG5cblx0fSxcblxuXHRzdXBwb3J0c0Zsb2F0VGV4dHVyZXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5zdXBwb3J0c0Zsb2F0VGV4dHVyZXMoKSBpcyBub3cgLmV4dGVuc2lvbnMuZ2V0KCBcXCdPRVNfdGV4dHVyZV9mbG9hdFxcJyApLicgKTtcblx0XHRyZXR1cm4gdGhpcy5leHRlbnNpb25zLmdldCggJ09FU190ZXh0dXJlX2Zsb2F0JyApO1xuXG5cdH0sXG5cdHN1cHBvcnRzSGFsZkZsb2F0VGV4dHVyZXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5zdXBwb3J0c0hhbGZGbG9hdFRleHR1cmVzKCkgaXMgbm93IC5leHRlbnNpb25zLmdldCggXFwnT0VTX3RleHR1cmVfaGFsZl9mbG9hdFxcJyApLicgKTtcblx0XHRyZXR1cm4gdGhpcy5leHRlbnNpb25zLmdldCggJ09FU190ZXh0dXJlX2hhbGZfZmxvYXQnICk7XG5cblx0fSxcblx0c3VwcG9ydHNTdGFuZGFyZERlcml2YXRpdmVzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAuc3VwcG9ydHNTdGFuZGFyZERlcml2YXRpdmVzKCkgaXMgbm93IC5leHRlbnNpb25zLmdldCggXFwnT0VTX3N0YW5kYXJkX2Rlcml2YXRpdmVzXFwnICkuJyApO1xuXHRcdHJldHVybiB0aGlzLmV4dGVuc2lvbnMuZ2V0KCAnT0VTX3N0YW5kYXJkX2Rlcml2YXRpdmVzJyApO1xuXG5cdH0sXG5cdHN1cHBvcnRzQ29tcHJlc3NlZFRleHR1cmVTM1RDOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAuc3VwcG9ydHNDb21wcmVzc2VkVGV4dHVyZVMzVEMoKSBpcyBub3cgLmV4dGVuc2lvbnMuZ2V0KCBcXCdXRUJHTF9jb21wcmVzc2VkX3RleHR1cmVfczN0Y1xcJyApLicgKTtcblx0XHRyZXR1cm4gdGhpcy5leHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9zM3RjJyApO1xuXG5cdH0sXG5cdHN1cHBvcnRzQ29tcHJlc3NlZFRleHR1cmVQVlJUQzogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLnN1cHBvcnRzQ29tcHJlc3NlZFRleHR1cmVQVlJUQygpIGlzIG5vdyAuZXh0ZW5zaW9ucy5nZXQoIFxcJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9wdnJ0Y1xcJyApLicgKTtcblx0XHRyZXR1cm4gdGhpcy5leHRlbnNpb25zLmdldCggJ1dFQkdMX2NvbXByZXNzZWRfdGV4dHVyZV9wdnJ0YycgKTtcblxuXHR9LFxuXHRzdXBwb3J0c0JsZW5kTWluTWF4OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAuc3VwcG9ydHNCbGVuZE1pbk1heCgpIGlzIG5vdyAuZXh0ZW5zaW9ucy5nZXQoIFxcJ0VYVF9ibGVuZF9taW5tYXhcXCcgKS4nICk7XG5cdFx0cmV0dXJuIHRoaXMuZXh0ZW5zaW9ucy5nZXQoICdFWFRfYmxlbmRfbWlubWF4JyApO1xuXG5cdH0sXG5cdHN1cHBvcnRzVmVydGV4VGV4dHVyZXM6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5zdXBwb3J0c1ZlcnRleFRleHR1cmVzKCkgaXMgbm93IC5jYXBhYmlsaXRpZXMudmVydGV4VGV4dHVyZXMuJyApO1xuXHRcdHJldHVybiB0aGlzLmNhcGFiaWxpdGllcy52ZXJ0ZXhUZXh0dXJlcztcblxuXHR9LFxuXHRzdXBwb3J0c0luc3RhbmNlZEFycmF5czogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLnN1cHBvcnRzSW5zdGFuY2VkQXJyYXlzKCkgaXMgbm93IC5leHRlbnNpb25zLmdldCggXFwnQU5HTEVfaW5zdGFuY2VkX2FycmF5c1xcJyApLicgKTtcblx0XHRyZXR1cm4gdGhpcy5leHRlbnNpb25zLmdldCggJ0FOR0xFX2luc3RhbmNlZF9hcnJheXMnICk7XG5cblx0fSxcblx0ZW5hYmxlU2Npc3NvclRlc3Q6IGZ1bmN0aW9uICggYm9vbGVhbiApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5lbmFibGVTY2lzc29yVGVzdCgpIGlzIG5vdyAuc2V0U2Npc3NvclRlc3QoKS4nICk7XG5cdFx0dGhpcy5zZXRTY2lzc29yVGVzdCggYm9vbGVhbiApO1xuXG5cdH0sXG5cdGluaXRNYXRlcmlhbDogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLmluaXRNYXRlcmlhbCgpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdGFkZFByZVBsdWdpbjogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLmFkZFByZVBsdWdpbigpIGhhcyBiZWVuIHJlbW92ZWQuJyApO1xuXG5cdH0sXG5cdGFkZFBvc3RQbHVnaW46IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyZXI6IC5hZGRQb3N0UGx1Z2luKCkgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0fSxcblx0dXBkYXRlU2hhZG93TWFwOiBmdW5jdGlvbiAoKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAudXBkYXRlU2hhZG93TWFwKCkgaGFzIGJlZW4gcmVtb3ZlZC4nICk7XG5cblx0fVxuXG59ICk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBXZWJHTFJlbmRlcmVyLnByb3RvdHlwZSwge1xuXG5cdHNoYWRvd01hcEVuYWJsZWQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuc2hhZG93TWFwLmVuYWJsZWQ7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLnNoYWRvd01hcEVuYWJsZWQgaXMgbm93IC5zaGFkb3dNYXAuZW5hYmxlZC4nICk7XG5cdFx0XHR0aGlzLnNoYWRvd01hcC5lbmFibGVkID0gdmFsdWU7XG5cblx0XHR9XG5cdH0sXG5cdHNoYWRvd01hcFR5cGU6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuc2hhZG93TWFwLnR5cGU7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJlcjogLnNoYWRvd01hcFR5cGUgaXMgbm93IC5zaGFkb3dNYXAudHlwZS4nICk7XG5cdFx0XHR0aGlzLnNoYWRvd01hcC50eXBlID0gdmFsdWU7XG5cblx0XHR9XG5cdH0sXG5cdHNoYWRvd01hcEN1bGxGYWNlOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLnNoYWRvd01hcC5jdWxsRmFjZTtcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlcmVyOiAuc2hhZG93TWFwQ3VsbEZhY2UgaXMgbm93IC5zaGFkb3dNYXAuY3VsbEZhY2UuJyApO1xuXHRcdFx0dGhpcy5zaGFkb3dNYXAuY3VsbEZhY2UgPSB2YWx1ZTtcblxuXHRcdH1cblx0fVxufSApO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggV2ViR0xTaGFkb3dNYXAucHJvdG90eXBlLCB7XG5cblx0Y3VsbEZhY2U6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMucmVuZGVyUmV2ZXJzZVNpZGVkID8gQ3VsbEZhY2VGcm9udCA6IEN1bGxGYWNlQmFjaztcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIGN1bGxGYWNlICkge1xuXG5cdFx0XHR2YXIgdmFsdWUgPSAoIGN1bGxGYWNlICE9PSBDdWxsRmFjZUJhY2sgKTtcblx0XHRcdGNvbnNvbGUud2FybiggXCJXZWJHTFJlbmRlcmVyOiAuc2hhZG93TWFwLmN1bGxGYWNlIGlzIGRlcHJlY2F0ZWQuIFNldCAuc2hhZG93TWFwLnJlbmRlclJldmVyc2VTaWRlZCB0byBcIiArIHZhbHVlICsgXCIuXCIgKTtcblx0XHRcdHRoaXMucmVuZGVyUmV2ZXJzZVNpZGVkID0gdmFsdWU7XG5cblx0XHR9XG5cdH1cblxufSApO1xuXG4vL1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyggV2ViR0xSZW5kZXJUYXJnZXQucHJvdG90eXBlLCB7XG5cblx0d3JhcFM6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC53cmFwUyBpcyBub3cgLnRleHR1cmUud3JhcFMuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMudGV4dHVyZS53cmFwUztcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLndyYXBTIGlzIG5vdyAudGV4dHVyZS53cmFwUy4nICk7XG5cdFx0XHR0aGlzLnRleHR1cmUud3JhcFMgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0d3JhcFQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC53cmFwVCBpcyBub3cgLnRleHR1cmUud3JhcFQuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMudGV4dHVyZS53cmFwVDtcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLndyYXBUIGlzIG5vdyAudGV4dHVyZS53cmFwVC4nICk7XG5cdFx0XHR0aGlzLnRleHR1cmUud3JhcFQgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0bWFnRmlsdGVyOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAubWFnRmlsdGVyIGlzIG5vdyAudGV4dHVyZS5tYWdGaWx0ZXIuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMudGV4dHVyZS5tYWdGaWx0ZXI7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC5tYWdGaWx0ZXIgaXMgbm93IC50ZXh0dXJlLm1hZ0ZpbHRlci4nICk7XG5cdFx0XHR0aGlzLnRleHR1cmUubWFnRmlsdGVyID0gdmFsdWU7XG5cblx0XHR9XG5cdH0sXG5cdG1pbkZpbHRlcjoge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLm1pbkZpbHRlciBpcyBub3cgLnRleHR1cmUubWluRmlsdGVyLicgKTtcblx0XHRcdHJldHVybiB0aGlzLnRleHR1cmUubWluRmlsdGVyO1xuXG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAubWluRmlsdGVyIGlzIG5vdyAudGV4dHVyZS5taW5GaWx0ZXIuJyApO1xuXHRcdFx0dGhpcy50ZXh0dXJlLm1pbkZpbHRlciA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRhbmlzb3Ryb3B5OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAuYW5pc290cm9weSBpcyBub3cgLnRleHR1cmUuYW5pc290cm9weS4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy50ZXh0dXJlLmFuaXNvdHJvcHk7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC5hbmlzb3Ryb3B5IGlzIG5vdyAudGV4dHVyZS5hbmlzb3Ryb3B5LicgKTtcblx0XHRcdHRoaXMudGV4dHVyZS5hbmlzb3Ryb3B5ID0gdmFsdWU7XG5cblx0XHR9XG5cdH0sXG5cdG9mZnNldDoge1xuXHRcdGdldDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLm9mZnNldCBpcyBub3cgLnRleHR1cmUub2Zmc2V0LicgKTtcblx0XHRcdHJldHVybiB0aGlzLnRleHR1cmUub2Zmc2V0O1xuXG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uICggdmFsdWUgKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAub2Zmc2V0IGlzIG5vdyAudGV4dHVyZS5vZmZzZXQuJyApO1xuXHRcdFx0dGhpcy50ZXh0dXJlLm9mZnNldCA9IHZhbHVlO1xuXG5cdFx0fVxuXHR9LFxuXHRyZXBlYXQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC5yZXBlYXQgaXMgbm93IC50ZXh0dXJlLnJlcGVhdC4nICk7XG5cdFx0XHRyZXR1cm4gdGhpcy50ZXh0dXJlLnJlcGVhdDtcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLnJlcGVhdCBpcyBub3cgLnRleHR1cmUucmVwZWF0LicgKTtcblx0XHRcdHRoaXMudGV4dHVyZS5yZXBlYXQgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0Zm9ybWF0OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAuZm9ybWF0IGlzIG5vdyAudGV4dHVyZS5mb3JtYXQuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMudGV4dHVyZS5mb3JtYXQ7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC5mb3JtYXQgaXMgbm93IC50ZXh0dXJlLmZvcm1hdC4nICk7XG5cdFx0XHR0aGlzLnRleHR1cmUuZm9ybWF0ID0gdmFsdWU7XG5cblx0XHR9XG5cdH0sXG5cdHR5cGU6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC50eXBlIGlzIG5vdyAudGV4dHVyZS50eXBlLicgKTtcblx0XHRcdHJldHVybiB0aGlzLnRleHR1cmUudHlwZTtcblxuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoIHZhbHVlICkge1xuXG5cdFx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5XZWJHTFJlbmRlclRhcmdldDogLnR5cGUgaXMgbm93IC50ZXh0dXJlLnR5cGUuJyApO1xuXHRcdFx0dGhpcy50ZXh0dXJlLnR5cGUgPSB2YWx1ZTtcblxuXHRcdH1cblx0fSxcblx0Z2VuZXJhdGVNaXBtYXBzOiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLldlYkdMUmVuZGVyVGFyZ2V0OiAuZ2VuZXJhdGVNaXBtYXBzIGlzIG5vdyAudGV4dHVyZS5nZW5lcmF0ZU1pcG1hcHMuJyApO1xuXHRcdFx0cmV0dXJuIHRoaXMudGV4dHVyZS5nZW5lcmF0ZU1pcG1hcHM7XG5cblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKCB2YWx1ZSApIHtcblxuXHRcdFx0Y29uc29sZS53YXJuKCAnVEhSRUUuV2ViR0xSZW5kZXJUYXJnZXQ6IC5nZW5lcmF0ZU1pcG1hcHMgaXMgbm93IC50ZXh0dXJlLmdlbmVyYXRlTWlwbWFwcy4nICk7XG5cdFx0XHR0aGlzLnRleHR1cmUuZ2VuZXJhdGVNaXBtYXBzID0gdmFsdWU7XG5cblx0XHR9XG5cdH1cblxufSApO1xuXG4vL1xuXG5BdWRpby5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICggZmlsZSApIHtcblxuXHRjb25zb2xlLndhcm4oICdUSFJFRS5BdWRpbzogLmxvYWQgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIFRIUkVFLkF1ZGlvTG9hZGVyIGluc3RlYWQuJyApO1xuXHR2YXIgc2NvcGUgPSB0aGlzO1xuXHR2YXIgYXVkaW9Mb2FkZXIgPSBuZXcgQXVkaW9Mb2FkZXIoKTtcblx0YXVkaW9Mb2FkZXIubG9hZCggZmlsZSwgZnVuY3Rpb24gKCBidWZmZXIgKSB7XG5cblx0XHRzY29wZS5zZXRCdWZmZXIoIGJ1ZmZlciApO1xuXG5cdH0gKTtcblx0cmV0dXJuIHRoaXM7XG5cbn07XG5cbkF1ZGlvQW5hbHlzZXIucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG5cblx0Y29uc29sZS53YXJuKCAnVEhSRUUuQXVkaW9BbmFseXNlcjogLmdldERhdGEoKSBpcyBub3cgLmdldEZyZXF1ZW5jeURhdGEoKS4nICk7XG5cdHJldHVybiB0aGlzLmdldEZyZXF1ZW5jeURhdGEoKTtcblxufTtcblxuLy9cblxudmFyIEdlb21ldHJ5VXRpbHMgPSB7XG5cblx0bWVyZ2U6IGZ1bmN0aW9uICggZ2VvbWV0cnkxLCBnZW9tZXRyeTIsIG1hdGVyaWFsSW5kZXhPZmZzZXQgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5HZW9tZXRyeVV0aWxzOiAubWVyZ2UoKSBoYXMgYmVlbiBtb3ZlZCB0byBHZW9tZXRyeS4gVXNlIGdlb21ldHJ5Lm1lcmdlKCBnZW9tZXRyeTIsIG1hdHJpeCwgbWF0ZXJpYWxJbmRleE9mZnNldCApIGluc3RlYWQuJyApO1xuXHRcdHZhciBtYXRyaXg7XG5cblx0XHRpZiAoIGdlb21ldHJ5Mi5pc01lc2ggKSB7XG5cblx0XHRcdGdlb21ldHJ5Mi5tYXRyaXhBdXRvVXBkYXRlICYmIGdlb21ldHJ5Mi51cGRhdGVNYXRyaXgoKTtcblxuXHRcdFx0bWF0cml4ID0gZ2VvbWV0cnkyLm1hdHJpeDtcblx0XHRcdGdlb21ldHJ5MiA9IGdlb21ldHJ5Mi5nZW9tZXRyeTtcblxuXHRcdH1cblxuXHRcdGdlb21ldHJ5MS5tZXJnZSggZ2VvbWV0cnkyLCBtYXRyaXgsIG1hdGVyaWFsSW5kZXhPZmZzZXQgKTtcblxuXHR9LFxuXG5cdGNlbnRlcjogZnVuY3Rpb24gKCBnZW9tZXRyeSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLkdlb21ldHJ5VXRpbHM6IC5jZW50ZXIoKSBoYXMgYmVlbiBtb3ZlZCB0byBHZW9tZXRyeS4gVXNlIGdlb21ldHJ5LmNlbnRlcigpIGluc3RlYWQuJyApO1xuXHRcdHJldHVybiBnZW9tZXRyeS5jZW50ZXIoKTtcblxuXHR9XG5cbn07XG5cbnZhciBJbWFnZVV0aWxzID0ge1xuXG5cdGNyb3NzT3JpZ2luOiB1bmRlZmluZWQsXG5cblx0bG9hZFRleHR1cmU6IGZ1bmN0aW9uICggdXJsLCBtYXBwaW5nLCBvbkxvYWQsIG9uRXJyb3IgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5JbWFnZVV0aWxzLmxvYWRUZXh0dXJlIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFVzZSBUSFJFRS5UZXh0dXJlTG9hZGVyKCkgaW5zdGVhZC4nICk7XG5cblx0XHR2YXIgbG9hZGVyID0gbmV3IFRleHR1cmVMb2FkZXIoKTtcblx0XHRsb2FkZXIuc2V0Q3Jvc3NPcmlnaW4oIHRoaXMuY3Jvc3NPcmlnaW4gKTtcblxuXHRcdHZhciB0ZXh0dXJlID0gbG9hZGVyLmxvYWQoIHVybCwgb25Mb2FkLCB1bmRlZmluZWQsIG9uRXJyb3IgKTtcblxuXHRcdGlmICggbWFwcGluZyApIHRleHR1cmUubWFwcGluZyA9IG1hcHBpbmc7XG5cblx0XHRyZXR1cm4gdGV4dHVyZTtcblxuXHR9LFxuXG5cdGxvYWRUZXh0dXJlQ3ViZTogZnVuY3Rpb24gKCB1cmxzLCBtYXBwaW5nLCBvbkxvYWQsIG9uRXJyb3IgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5JbWFnZVV0aWxzLmxvYWRUZXh0dXJlQ3ViZSBoYXMgYmVlbiBkZXByZWNhdGVkLiBVc2UgVEhSRUUuQ3ViZVRleHR1cmVMb2FkZXIoKSBpbnN0ZWFkLicgKTtcblxuXHRcdHZhciBsb2FkZXIgPSBuZXcgQ3ViZVRleHR1cmVMb2FkZXIoKTtcblx0XHRsb2FkZXIuc2V0Q3Jvc3NPcmlnaW4oIHRoaXMuY3Jvc3NPcmlnaW4gKTtcblxuXHRcdHZhciB0ZXh0dXJlID0gbG9hZGVyLmxvYWQoIHVybHMsIG9uTG9hZCwgdW5kZWZpbmVkLCBvbkVycm9yICk7XG5cblx0XHRpZiAoIG1hcHBpbmcgKSB0ZXh0dXJlLm1hcHBpbmcgPSBtYXBwaW5nO1xuXG5cdFx0cmV0dXJuIHRleHR1cmU7XG5cblx0fSxcblxuXHRsb2FkQ29tcHJlc3NlZFRleHR1cmU6IGZ1bmN0aW9uICgpIHtcblxuXHRcdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5JbWFnZVV0aWxzLmxvYWRDb21wcmVzc2VkVGV4dHVyZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuRERTTG9hZGVyIGluc3RlYWQuJyApO1xuXG5cdH0sXG5cblx0bG9hZENvbXByZXNzZWRUZXh0dXJlQ3ViZTogZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLkltYWdlVXRpbHMubG9hZENvbXByZXNzZWRUZXh0dXJlQ3ViZSBoYXMgYmVlbiByZW1vdmVkLiBVc2UgVEhSRUUuRERTTG9hZGVyIGluc3RlYWQuJyApO1xuXG5cdH1cblxufTtcblxuLy9cblxuZnVuY3Rpb24gUHJvamVjdG9yKCkge1xuXG5cdGNvbnNvbGUuZXJyb3IoICdUSFJFRS5Qcm9qZWN0b3IgaGFzIGJlZW4gbW92ZWQgdG8gL2V4YW1wbGVzL2pzL3JlbmRlcmVycy9Qcm9qZWN0b3IuanMuJyApO1xuXG5cdHRoaXMucHJvamVjdFZlY3RvciA9IGZ1bmN0aW9uICggdmVjdG9yLCBjYW1lcmEgKSB7XG5cblx0XHRjb25zb2xlLndhcm4oICdUSFJFRS5Qcm9qZWN0b3I6IC5wcm9qZWN0VmVjdG9yKCkgaXMgbm93IHZlY3Rvci5wcm9qZWN0KCkuJyApO1xuXHRcdHZlY3Rvci5wcm9qZWN0KCBjYW1lcmEgKTtcblxuXHR9O1xuXG5cdHRoaXMudW5wcm9qZWN0VmVjdG9yID0gZnVuY3Rpb24gKCB2ZWN0b3IsIGNhbWVyYSApIHtcblxuXHRcdGNvbnNvbGUud2FybiggJ1RIUkVFLlByb2plY3RvcjogLnVucHJvamVjdFZlY3RvcigpIGlzIG5vdyB2ZWN0b3IudW5wcm9qZWN0KCkuJyApO1xuXHRcdHZlY3Rvci51bnByb2plY3QoIGNhbWVyYSApO1xuXG5cdH07XG5cblx0dGhpcy5waWNraW5nUmF5ID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0Y29uc29sZS5lcnJvciggJ1RIUkVFLlByb2plY3RvcjogLnBpY2tpbmdSYXkoKSBpcyBub3cgcmF5Y2FzdGVyLnNldEZyb21DYW1lcmEoKS4nICk7XG5cblx0fTtcblxufVxuXG4vL1xuXG5mdW5jdGlvbiBDYW52YXNSZW5kZXJlcigpIHtcblxuXHRjb25zb2xlLmVycm9yKCAnVEhSRUUuQ2FudmFzUmVuZGVyZXIgaGFzIGJlZW4gbW92ZWQgdG8gL2V4YW1wbGVzL2pzL3JlbmRlcmVycy9DYW52YXNSZW5kZXJlci5qcycgKTtcblxuXHR0aGlzLmRvbUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJywgJ2NhbnZhcycgKTtcblx0dGhpcy5jbGVhciA9IGZ1bmN0aW9uICgpIHt9O1xuXHR0aGlzLnJlbmRlciA9IGZ1bmN0aW9uICgpIHt9O1xuXHR0aGlzLnNldENsZWFyQ29sb3IgPSBmdW5jdGlvbiAoKSB7fTtcblx0dGhpcy5zZXRTaXplID0gZnVuY3Rpb24gKCkge307XG5cbn1cblxuZXhwb3J0IHsgV2ViR0xSZW5kZXJUYXJnZXRDdWJlLCBXZWJHTFJlbmRlclRhcmdldCwgV2ViR0xSZW5kZXJlciwgU2hhZGVyTGliLCBVbmlmb3Jtc0xpYiwgVW5pZm9ybXNVdGlscywgU2hhZGVyQ2h1bmssIEZvZ0V4cDIsIEZvZywgU2NlbmUsIExlbnNGbGFyZSwgU3ByaXRlLCBMT0QsIFNraW5uZWRNZXNoLCBTa2VsZXRvbiwgQm9uZSwgTWVzaCwgTGluZVNlZ21lbnRzLCBMaW5lTG9vcCwgTGluZSwgUG9pbnRzLCBHcm91cCwgVmlkZW9UZXh0dXJlLCBEYXRhVGV4dHVyZSwgQ29tcHJlc3NlZFRleHR1cmUsIEN1YmVUZXh0dXJlLCBDYW52YXNUZXh0dXJlLCBEZXB0aFRleHR1cmUsIFRleHR1cmUsIENvbXByZXNzZWRUZXh0dXJlTG9hZGVyLCBEYXRhVGV4dHVyZUxvYWRlciwgQ3ViZVRleHR1cmVMb2FkZXIsIFRleHR1cmVMb2FkZXIsIE9iamVjdExvYWRlciwgTWF0ZXJpYWxMb2FkZXIsIEJ1ZmZlckdlb21ldHJ5TG9hZGVyLCBEZWZhdWx0TG9hZGluZ01hbmFnZXIsIExvYWRpbmdNYW5hZ2VyLCBKU09OTG9hZGVyLCBJbWFnZUxvYWRlciwgRm9udExvYWRlciwgRmlsZUxvYWRlciwgTG9hZGVyLCBDYWNoZSwgQXVkaW9Mb2FkZXIsIFNwb3RMaWdodFNoYWRvdywgU3BvdExpZ2h0LCBQb2ludExpZ2h0LCBSZWN0QXJlYUxpZ2h0LCBIZW1pc3BoZXJlTGlnaHQsIERpcmVjdGlvbmFsTGlnaHRTaGFkb3csIERpcmVjdGlvbmFsTGlnaHQsIEFtYmllbnRMaWdodCwgTGlnaHRTaGFkb3csIExpZ2h0LCBTdGVyZW9DYW1lcmEsIFBlcnNwZWN0aXZlQ2FtZXJhLCBPcnRob2dyYXBoaWNDYW1lcmEsIEN1YmVDYW1lcmEsIEFycmF5Q2FtZXJhLCBDYW1lcmEsIEF1ZGlvTGlzdGVuZXIsIFBvc2l0aW9uYWxBdWRpbywgQXVkaW9Db250ZXh0LCBBdWRpb0FuYWx5c2VyLCBBdWRpbywgVmVjdG9yS2V5ZnJhbWVUcmFjaywgU3RyaW5nS2V5ZnJhbWVUcmFjaywgUXVhdGVybmlvbktleWZyYW1lVHJhY2ssIE51bWJlcktleWZyYW1lVHJhY2ssIENvbG9yS2V5ZnJhbWVUcmFjaywgQm9vbGVhbktleWZyYW1lVHJhY2ssIFByb3BlcnR5TWl4ZXIsIFByb3BlcnR5QmluZGluZywgS2V5ZnJhbWVUcmFjaywgQW5pbWF0aW9uVXRpbHMsIEFuaW1hdGlvbk9iamVjdEdyb3VwLCBBbmltYXRpb25NaXhlciwgQW5pbWF0aW9uQ2xpcCwgVW5pZm9ybSwgSW5zdGFuY2VkQnVmZmVyR2VvbWV0cnksIEJ1ZmZlckdlb21ldHJ5LCBHZW9tZXRyeUlkQ291bnQsIEdlb21ldHJ5LCBJbnRlcmxlYXZlZEJ1ZmZlckF0dHJpYnV0ZSwgSW5zdGFuY2VkSW50ZXJsZWF2ZWRCdWZmZXIsIEludGVybGVhdmVkQnVmZmVyLCBJbnN0YW5jZWRCdWZmZXJBdHRyaWJ1dGUsIEZhY2UzLCBPYmplY3QzRCwgUmF5Y2FzdGVyLCBMYXllcnMsIEV2ZW50RGlzcGF0Y2hlciwgQ2xvY2ssIFF1YXRlcm5pb25MaW5lYXJJbnRlcnBvbGFudCwgTGluZWFySW50ZXJwb2xhbnQsIERpc2NyZXRlSW50ZXJwb2xhbnQsIEN1YmljSW50ZXJwb2xhbnQsIEludGVycG9sYW50LCBUcmlhbmdsZSwgX01hdGggYXMgTWF0aCwgU3BoZXJpY2FsLCBDeWxpbmRyaWNhbCwgUGxhbmUsIEZydXN0dW0sIFNwaGVyZSwgUmF5LCBNYXRyaXg0LCBNYXRyaXgzLCBCb3gzLCBCb3gyLCBMaW5lMywgRXVsZXIsIFZlY3RvcjQsIFZlY3RvcjMsIFZlY3RvcjIsIFF1YXRlcm5pb24sIENvbG9yLCBNb3JwaEJsZW5kTWVzaCwgSW1tZWRpYXRlUmVuZGVyT2JqZWN0LCBWZXJ0ZXhOb3JtYWxzSGVscGVyLCBTcG90TGlnaHRIZWxwZXIsIFNrZWxldG9uSGVscGVyLCBQb2ludExpZ2h0SGVscGVyLCBSZWN0QXJlYUxpZ2h0SGVscGVyLCBIZW1pc3BoZXJlTGlnaHRIZWxwZXIsIEdyaWRIZWxwZXIsIFBvbGFyR3JpZEhlbHBlciwgRmFjZU5vcm1hbHNIZWxwZXIsIERpcmVjdGlvbmFsTGlnaHRIZWxwZXIsIENhbWVyYUhlbHBlciwgQm94SGVscGVyLCBBcnJvd0hlbHBlciwgQXhpc0hlbHBlciwgQ2F0bXVsbFJvbUN1cnZlMywgQ3ViaWNCZXppZXJDdXJ2ZTMsIFF1YWRyYXRpY0JlemllckN1cnZlMywgTGluZUN1cnZlMywgQXJjQ3VydmUsIEVsbGlwc2VDdXJ2ZSwgU3BsaW5lQ3VydmUsIEN1YmljQmV6aWVyQ3VydmUsIFF1YWRyYXRpY0JlemllckN1cnZlLCBMaW5lQ3VydmUsIFNoYXBlLCBQYXRoLCBTaGFwZVBhdGgsIEZvbnQsIEN1cnZlUGF0aCwgQ3VydmUsIFNoYXBlVXRpbHMsIFNjZW5lVXRpbHMsIFdpcmVmcmFtZUdlb21ldHJ5LCBQYXJhbWV0cmljR2VvbWV0cnksIFBhcmFtZXRyaWNCdWZmZXJHZW9tZXRyeSwgVGV0cmFoZWRyb25HZW9tZXRyeSwgVGV0cmFoZWRyb25CdWZmZXJHZW9tZXRyeSwgT2N0YWhlZHJvbkdlb21ldHJ5LCBPY3RhaGVkcm9uQnVmZmVyR2VvbWV0cnksIEljb3NhaGVkcm9uR2VvbWV0cnksIEljb3NhaGVkcm9uQnVmZmVyR2VvbWV0cnksIERvZGVjYWhlZHJvbkdlb21ldHJ5LCBEb2RlY2FoZWRyb25CdWZmZXJHZW9tZXRyeSwgUG9seWhlZHJvbkdlb21ldHJ5LCBQb2x5aGVkcm9uQnVmZmVyR2VvbWV0cnksIFR1YmVHZW9tZXRyeSwgVHViZUJ1ZmZlckdlb21ldHJ5LCBUb3J1c0tub3RHZW9tZXRyeSwgVG9ydXNLbm90QnVmZmVyR2VvbWV0cnksIFRvcnVzR2VvbWV0cnksIFRvcnVzQnVmZmVyR2VvbWV0cnksIFRleHRHZW9tZXRyeSwgVGV4dEJ1ZmZlckdlb21ldHJ5LCBTcGhlcmVHZW9tZXRyeSwgU3BoZXJlQnVmZmVyR2VvbWV0cnksIFJpbmdHZW9tZXRyeSwgUmluZ0J1ZmZlckdlb21ldHJ5LCBQbGFuZUdlb21ldHJ5LCBQbGFuZUJ1ZmZlckdlb21ldHJ5LCBMYXRoZUdlb21ldHJ5LCBMYXRoZUJ1ZmZlckdlb21ldHJ5LCBTaGFwZUdlb21ldHJ5LCBTaGFwZUJ1ZmZlckdlb21ldHJ5LCBFeHRydWRlR2VvbWV0cnksIEV4dHJ1ZGVCdWZmZXJHZW9tZXRyeSwgRWRnZXNHZW9tZXRyeSwgQ29uZUdlb21ldHJ5LCBDb25lQnVmZmVyR2VvbWV0cnksIEN5bGluZGVyR2VvbWV0cnksIEN5bGluZGVyQnVmZmVyR2VvbWV0cnksIENpcmNsZUdlb21ldHJ5LCBDaXJjbGVCdWZmZXJHZW9tZXRyeSwgQm94R2VvbWV0cnksIEJveEJ1ZmZlckdlb21ldHJ5LCBTaGFkb3dNYXRlcmlhbCwgU3ByaXRlTWF0ZXJpYWwsIFJhd1NoYWRlck1hdGVyaWFsLCBTaGFkZXJNYXRlcmlhbCwgUG9pbnRzTWF0ZXJpYWwsIE1lc2hQaHlzaWNhbE1hdGVyaWFsLCBNZXNoU3RhbmRhcmRNYXRlcmlhbCwgTWVzaFBob25nTWF0ZXJpYWwsIE1lc2hUb29uTWF0ZXJpYWwsIE1lc2hOb3JtYWxNYXRlcmlhbCwgTWVzaExhbWJlcnRNYXRlcmlhbCwgTWVzaERlcHRoTWF0ZXJpYWwsIE1lc2hCYXNpY01hdGVyaWFsLCBMaW5lRGFzaGVkTWF0ZXJpYWwsIExpbmVCYXNpY01hdGVyaWFsLCBNYXRlcmlhbCwgRmxvYXQ2NEJ1ZmZlckF0dHJpYnV0ZSwgRmxvYXQzMkJ1ZmZlckF0dHJpYnV0ZSwgVWludDMyQnVmZmVyQXR0cmlidXRlLCBJbnQzMkJ1ZmZlckF0dHJpYnV0ZSwgVWludDE2QnVmZmVyQXR0cmlidXRlLCBJbnQxNkJ1ZmZlckF0dHJpYnV0ZSwgVWludDhDbGFtcGVkQnVmZmVyQXR0cmlidXRlLCBVaW50OEJ1ZmZlckF0dHJpYnV0ZSwgSW50OEJ1ZmZlckF0dHJpYnV0ZSwgQnVmZmVyQXR0cmlidXRlLCBSRVZJU0lPTiwgTU9VU0UsIEN1bGxGYWNlTm9uZSwgQ3VsbEZhY2VCYWNrLCBDdWxsRmFjZUZyb250LCBDdWxsRmFjZUZyb250QmFjaywgRnJvbnRGYWNlRGlyZWN0aW9uQ1csIEZyb250RmFjZURpcmVjdGlvbkNDVywgQmFzaWNTaGFkb3dNYXAsIFBDRlNoYWRvd01hcCwgUENGU29mdFNoYWRvd01hcCwgRnJvbnRTaWRlLCBCYWNrU2lkZSwgRG91YmxlU2lkZSwgRmxhdFNoYWRpbmcsIFNtb290aFNoYWRpbmcsIE5vQ29sb3JzLCBGYWNlQ29sb3JzLCBWZXJ0ZXhDb2xvcnMsIE5vQmxlbmRpbmcsIE5vcm1hbEJsZW5kaW5nLCBBZGRpdGl2ZUJsZW5kaW5nLCBTdWJ0cmFjdGl2ZUJsZW5kaW5nLCBNdWx0aXBseUJsZW5kaW5nLCBDdXN0b21CbGVuZGluZywgQWRkRXF1YXRpb24sIFN1YnRyYWN0RXF1YXRpb24sIFJldmVyc2VTdWJ0cmFjdEVxdWF0aW9uLCBNaW5FcXVhdGlvbiwgTWF4RXF1YXRpb24sIFplcm9GYWN0b3IsIE9uZUZhY3RvciwgU3JjQ29sb3JGYWN0b3IsIE9uZU1pbnVzU3JjQ29sb3JGYWN0b3IsIFNyY0FscGhhRmFjdG9yLCBPbmVNaW51c1NyY0FscGhhRmFjdG9yLCBEc3RBbHBoYUZhY3RvciwgT25lTWludXNEc3RBbHBoYUZhY3RvciwgRHN0Q29sb3JGYWN0b3IsIE9uZU1pbnVzRHN0Q29sb3JGYWN0b3IsIFNyY0FscGhhU2F0dXJhdGVGYWN0b3IsIE5ldmVyRGVwdGgsIEFsd2F5c0RlcHRoLCBMZXNzRGVwdGgsIExlc3NFcXVhbERlcHRoLCBFcXVhbERlcHRoLCBHcmVhdGVyRXF1YWxEZXB0aCwgR3JlYXRlckRlcHRoLCBOb3RFcXVhbERlcHRoLCBNdWx0aXBseU9wZXJhdGlvbiwgTWl4T3BlcmF0aW9uLCBBZGRPcGVyYXRpb24sIE5vVG9uZU1hcHBpbmcsIExpbmVhclRvbmVNYXBwaW5nLCBSZWluaGFyZFRvbmVNYXBwaW5nLCBVbmNoYXJ0ZWQyVG9uZU1hcHBpbmcsIENpbmVvblRvbmVNYXBwaW5nLCBVVk1hcHBpbmcsIEN1YmVSZWZsZWN0aW9uTWFwcGluZywgQ3ViZVJlZnJhY3Rpb25NYXBwaW5nLCBFcXVpcmVjdGFuZ3VsYXJSZWZsZWN0aW9uTWFwcGluZywgRXF1aXJlY3Rhbmd1bGFyUmVmcmFjdGlvbk1hcHBpbmcsIFNwaGVyaWNhbFJlZmxlY3Rpb25NYXBwaW5nLCBDdWJlVVZSZWZsZWN0aW9uTWFwcGluZywgQ3ViZVVWUmVmcmFjdGlvbk1hcHBpbmcsIFJlcGVhdFdyYXBwaW5nLCBDbGFtcFRvRWRnZVdyYXBwaW5nLCBNaXJyb3JlZFJlcGVhdFdyYXBwaW5nLCBOZWFyZXN0RmlsdGVyLCBOZWFyZXN0TWlwTWFwTmVhcmVzdEZpbHRlciwgTmVhcmVzdE1pcE1hcExpbmVhckZpbHRlciwgTGluZWFyRmlsdGVyLCBMaW5lYXJNaXBNYXBOZWFyZXN0RmlsdGVyLCBMaW5lYXJNaXBNYXBMaW5lYXJGaWx0ZXIsIFVuc2lnbmVkQnl0ZVR5cGUsIEJ5dGVUeXBlLCBTaG9ydFR5cGUsIFVuc2lnbmVkU2hvcnRUeXBlLCBJbnRUeXBlLCBVbnNpZ25lZEludFR5cGUsIEZsb2F0VHlwZSwgSGFsZkZsb2F0VHlwZSwgVW5zaWduZWRTaG9ydDQ0NDRUeXBlLCBVbnNpZ25lZFNob3J0NTU1MVR5cGUsIFVuc2lnbmVkU2hvcnQ1NjVUeXBlLCBVbnNpZ25lZEludDI0OFR5cGUsIEFscGhhRm9ybWF0LCBSR0JGb3JtYXQsIFJHQkFGb3JtYXQsIEx1bWluYW5jZUZvcm1hdCwgTHVtaW5hbmNlQWxwaGFGb3JtYXQsIFJHQkVGb3JtYXQsIERlcHRoRm9ybWF0LCBEZXB0aFN0ZW5jaWxGb3JtYXQsIFJHQl9TM1RDX0RYVDFfRm9ybWF0LCBSR0JBX1MzVENfRFhUMV9Gb3JtYXQsIFJHQkFfUzNUQ19EWFQzX0Zvcm1hdCwgUkdCQV9TM1RDX0RYVDVfRm9ybWF0LCBSR0JfUFZSVENfNEJQUFYxX0Zvcm1hdCwgUkdCX1BWUlRDXzJCUFBWMV9Gb3JtYXQsIFJHQkFfUFZSVENfNEJQUFYxX0Zvcm1hdCwgUkdCQV9QVlJUQ18yQlBQVjFfRm9ybWF0LCBSR0JfRVRDMV9Gb3JtYXQsIExvb3BPbmNlLCBMb29wUmVwZWF0LCBMb29wUGluZ1BvbmcsIEludGVycG9sYXRlRGlzY3JldGUsIEludGVycG9sYXRlTGluZWFyLCBJbnRlcnBvbGF0ZVNtb290aCwgWmVyb0N1cnZhdHVyZUVuZGluZywgWmVyb1Nsb3BlRW5kaW5nLCBXcmFwQXJvdW5kRW5kaW5nLCBUcmlhbmdsZXNEcmF3TW9kZSwgVHJpYW5nbGVTdHJpcERyYXdNb2RlLCBUcmlhbmdsZUZhbkRyYXdNb2RlLCBMaW5lYXJFbmNvZGluZywgc1JHQkVuY29kaW5nLCBHYW1tYUVuY29kaW5nLCBSR0JFRW5jb2RpbmcsIExvZ0x1dkVuY29kaW5nLCBSR0JNN0VuY29kaW5nLCBSR0JNMTZFbmNvZGluZywgUkdCREVuY29kaW5nLCBCYXNpY0RlcHRoUGFja2luZywgUkdCQURlcHRoUGFja2luZywgQm94R2VvbWV0cnkgYXMgQ3ViZUdlb21ldHJ5LCBGYWNlNCwgTGluZVN0cmlwLCBMaW5lUGllY2VzLCBNZXNoRmFjZU1hdGVyaWFsLCBNdWx0aU1hdGVyaWFsLCBQb2ludENsb3VkLCBQYXJ0aWNsZSwgUGFydGljbGVTeXN0ZW0sIFBvaW50Q2xvdWRNYXRlcmlhbCwgUGFydGljbGVCYXNpY01hdGVyaWFsLCBQYXJ0aWNsZVN5c3RlbU1hdGVyaWFsLCBWZXJ0ZXgsIER5bmFtaWNCdWZmZXJBdHRyaWJ1dGUsIEludDhBdHRyaWJ1dGUsIFVpbnQ4QXR0cmlidXRlLCBVaW50OENsYW1wZWRBdHRyaWJ1dGUsIEludDE2QXR0cmlidXRlLCBVaW50MTZBdHRyaWJ1dGUsIEludDMyQXR0cmlidXRlLCBVaW50MzJBdHRyaWJ1dGUsIEZsb2F0MzJBdHRyaWJ1dGUsIEZsb2F0NjRBdHRyaWJ1dGUsIENsb3NlZFNwbGluZUN1cnZlMywgU3BsaW5lQ3VydmUzLCBTcGxpbmUsIEJvdW5kaW5nQm94SGVscGVyLCBFZGdlc0hlbHBlciwgV2lyZWZyYW1lSGVscGVyLCBYSFJMb2FkZXIsIEJpbmFyeVRleHR1cmVMb2FkZXIsIEdlb21ldHJ5VXRpbHMsIEltYWdlVXRpbHMsIFByb2plY3RvciwgQ2FudmFzUmVuZGVyZXIgfTtcbiIsImV4cG9ydCB7IF90eXBlb2YgYXMgdHlwZW9mLCBfanN4IGFzIGpzeCwgX2FzeW5jSXRlcmF0b3IgYXMgYXN5bmNJdGVyYXRvciwgX0F3YWl0VmFsdWUgYXMgQXdhaXRWYWx1ZSwgX0FzeW5jR2VuZXJhdG9yIGFzIEFzeW5jR2VuZXJhdG9yLCBfd3JhcEFzeW5jR2VuZXJhdG9yIGFzIHdyYXBBc3luY0dlbmVyYXRvciwgX2F3YWl0QXN5bmNHZW5lcmF0b3IgYXMgYXdhaXRBc3luY0dlbmVyYXRvciwgX2FzeW5jR2VuZXJhdG9yRGVsZWdhdGUgYXMgYXN5bmNHZW5lcmF0b3JEZWxlZ2F0ZSwgX2FzeW5jVG9HZW5lcmF0b3IgYXMgYXN5bmNUb0dlbmVyYXRvciwgX2NsYXNzQ2FsbENoZWNrIGFzIGNsYXNzQ2FsbENoZWNrLCBfY3JlYXRlQ2xhc3MgYXMgY3JlYXRlQ2xhc3MsIF9kZWZpbmVFbnVtZXJhYmxlUHJvcGVydGllcyBhcyBkZWZpbmVFbnVtZXJhYmxlUHJvcGVydGllcywgX2RlZmF1bHRzIGFzIGRlZmF1bHRzLCBfZGVmaW5lUHJvcGVydHkgYXMgZGVmaW5lUHJvcGVydHksIF9leHRlbmRzIGFzIGV4dGVuZHMsIF9vYmplY3RTcHJlYWQgYXMgb2JqZWN0U3ByZWFkLCBfaW5oZXJpdHMgYXMgaW5oZXJpdHMsIF9pbmhlcml0c0xvb3NlIGFzIGluaGVyaXRzTG9vc2UsIF9nZXRQcm90b3R5cGVPZiBhcyBnZXRQcm90b3R5cGVPZiwgX3NldFByb3RvdHlwZU9mIGFzIHNldFByb3RvdHlwZU9mLCBfY29uc3RydWN0IGFzIGNvbnN0cnVjdCwgX3dyYXBOYXRpdmVTdXBlciBhcyB3cmFwTmF0aXZlU3VwZXIsIF9pbnN0YW5jZW9mIGFzIGluc3RhbmNlb2YsIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgYXMgaW50ZXJvcFJlcXVpcmVEZWZhdWx0LCBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCBhcyBpbnRlcm9wUmVxdWlyZVdpbGRjYXJkLCBfbmV3QXJyb3dDaGVjayBhcyBuZXdBcnJvd0NoZWNrLCBfb2JqZWN0RGVzdHJ1Y3R1cmluZ0VtcHR5IGFzIG9iamVjdERlc3RydWN0dXJpbmdFbXB0eSwgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGFzIG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGFzIGFzc2VydFRoaXNJbml0aWFsaXplZCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gYXMgcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiwgX3N1cGVyUHJvcEJhc2UgYXMgc3VwZXJQcm9wQmFzZSwgX2dldCBhcyBnZXQsIF9zZXQgYXMgc2V0LCBfdGFnZ2VkVGVtcGxhdGVMaXRlcmFsIGFzIHRhZ2dlZFRlbXBsYXRlTGl0ZXJhbCwgX3RhZ2dlZFRlbXBsYXRlTGl0ZXJhbExvb3NlIGFzIHRhZ2dlZFRlbXBsYXRlTGl0ZXJhbExvb3NlLCBfdGVtcG9yYWxSZWYgYXMgdGVtcG9yYWxSZWYsIF9yZWFkT25seUVycm9yIGFzIHJlYWRPbmx5RXJyb3IsIF9jbGFzc05hbWVURFpFcnJvciBhcyBjbGFzc05hbWVURFpFcnJvciwgX3RlbXBvcmFsVW5kZWZpbmVkIGFzIHRlbXBvcmFsVW5kZWZpbmVkLCBfc2xpY2VkVG9BcnJheSBhcyBzbGljZWRUb0FycmF5LCBfc2xpY2VkVG9BcnJheUxvb3NlIGFzIHNsaWNlZFRvQXJyYXlMb29zZSwgX3RvQXJyYXkgYXMgdG9BcnJheSwgX3RvQ29uc3VtYWJsZUFycmF5IGFzIHRvQ29uc3VtYWJsZUFycmF5LCBfYXJyYXlXaXRob3V0SG9sZXMgYXMgYXJyYXlXaXRob3V0SG9sZXMsIF9hcnJheVdpdGhIb2xlcyBhcyBhcnJheVdpdGhIb2xlcywgX2l0ZXJhYmxlVG9BcnJheSBhcyBpdGVyYWJsZVRvQXJyYXksIF9pdGVyYWJsZVRvQXJyYXlMaW1pdCBhcyBpdGVyYWJsZVRvQXJyYXlMaW1pdCwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0TG9vc2UgYXMgaXRlcmFibGVUb0FycmF5TGltaXRMb29zZSwgX25vbkl0ZXJhYmxlU3ByZWFkIGFzIG5vbkl0ZXJhYmxlU3ByZWFkLCBfbm9uSXRlcmFibGVSZXN0IGFzIG5vbkl0ZXJhYmxlUmVzdCwgX3NraXBGaXJzdEdlbmVyYXRvck5leHQgYXMgc2tpcEZpcnN0R2VuZXJhdG9yTmV4dCwgX3RvUHJvcGVydHlLZXkgYXMgdG9Qcm9wZXJ0eUtleSwgX2luaXRpYWxpemVyV2FybmluZ0hlbHBlciBhcyBpbml0aWFsaXplcldhcm5pbmdIZWxwZXIsIF9pbml0aWFsaXplckRlZmluZVByb3BlcnR5IGFzIGluaXRpYWxpemVyRGVmaW5lUHJvcGVydHksIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IgYXMgYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yLCBfY2xhc3NQcml2YXRlRmllbGRMb29zZUtleSBhcyBjbGFzc1ByaXZhdGVGaWVsZExvb3NlS2V5LCBfY2xhc3NQcml2YXRlRmllbGRMb29zZUJhc2UgYXMgY2xhc3NQcml2YXRlRmllbGRMb29zZUJhc2UsIF9jbGFzc1ByaXZhdGVGaWVsZEdldCBhcyBjbGFzc1ByaXZhdGVGaWVsZEdldCwgX2NsYXNzUHJpdmF0ZUZpZWxkU2V0IGFzIGNsYXNzUHJpdmF0ZUZpZWxkU2V0IH07XG5cbmZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikge1xuICAgIF90eXBlb2YgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIG9iajtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIF90eXBlb2YgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbn1cblxudmFyIFJFQUNUX0VMRU1FTlRfVFlQRTtcblxuZnVuY3Rpb24gX2pzeCh0eXBlLCBwcm9wcywga2V5LCBjaGlsZHJlbikge1xuICBpZiAoIVJFQUNUX0VMRU1FTlRfVFlQRSkge1xuICAgIFJFQUNUX0VMRU1FTlRfVFlQRSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuZm9yICYmIFN5bWJvbC5mb3IoXCJyZWFjdC5lbGVtZW50XCIpIHx8IDB4ZWFjNztcbiAgfVxuXG4gIHZhciBkZWZhdWx0UHJvcHMgPSB0eXBlICYmIHR5cGUuZGVmYXVsdFByb3BzO1xuICB2YXIgY2hpbGRyZW5MZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoIC0gMztcblxuICBpZiAoIXByb3BzICYmIGNoaWxkcmVuTGVuZ3RoICE9PSAwKSB7XG4gICAgcHJvcHMgPSB7XG4gICAgICBjaGlsZHJlbjogdm9pZCAwXG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9wcyAmJiBkZWZhdWx0UHJvcHMpIHtcbiAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBkZWZhdWx0UHJvcHMpIHtcbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHZvaWQgMCkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICghcHJvcHMpIHtcbiAgICBwcm9wcyA9IGRlZmF1bHRQcm9wcyB8fCB7fTtcbiAgfVxuXG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBuZXcgQXJyYXkoY2hpbGRyZW5MZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbkxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGlsZEFycmF5W2ldID0gYXJndW1lbnRzW2kgKyAzXTtcbiAgICB9XG5cbiAgICBwcm9wcy5jaGlsZHJlbiA9IGNoaWxkQXJyYXk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9FTEVNRU5UX1RZUEUsXG4gICAgdHlwZTogdHlwZSxcbiAgICBrZXk6IGtleSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6ICcnICsga2V5LFxuICAgIHJlZjogbnVsbCxcbiAgICBwcm9wczogcHJvcHMsXG4gICAgX293bmVyOiBudWxsXG4gIH07XG59XG5cbmZ1bmN0aW9uIF9hc3luY0l0ZXJhdG9yKGl0ZXJhYmxlKSB7XG4gIHZhciBtZXRob2Q7XG5cbiAgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGlmIChTeW1ib2wuYXN5bmNJdGVyYXRvcikge1xuICAgICAgbWV0aG9kID0gaXRlcmFibGVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdO1xuICAgICAgaWYgKG1ldGhvZCAhPSBudWxsKSByZXR1cm4gbWV0aG9kLmNhbGwoaXRlcmFibGUpO1xuICAgIH1cblxuICAgIGlmIChTeW1ib2wuaXRlcmF0b3IpIHtcbiAgICAgIG1ldGhvZCA9IGl0ZXJhYmxlW1N5bWJvbC5pdGVyYXRvcl07XG4gICAgICBpZiAobWV0aG9kICE9IG51bGwpIHJldHVybiBtZXRob2QuY2FsbChpdGVyYWJsZSk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBpcyBub3QgYXN5bmMgaXRlcmFibGVcIik7XG59XG5cbmZ1bmN0aW9uIF9Bd2FpdFZhbHVlKHZhbHVlKSB7XG4gIHRoaXMud3JhcHBlZCA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBfQXN5bmNHZW5lcmF0b3IoZ2VuKSB7XG4gIHZhciBmcm9udCwgYmFjaztcblxuICBmdW5jdGlvbiBzZW5kKGtleSwgYXJnKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZXF1ZXN0ID0ge1xuICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgYXJnOiBhcmcsXG4gICAgICAgIHJlc29sdmU6IHJlc29sdmUsXG4gICAgICAgIHJlamVjdDogcmVqZWN0LFxuICAgICAgICBuZXh0OiBudWxsXG4gICAgICB9O1xuXG4gICAgICBpZiAoYmFjaykge1xuICAgICAgICBiYWNrID0gYmFjay5uZXh0ID0gcmVxdWVzdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyb250ID0gYmFjayA9IHJlcXVlc3Q7XG4gICAgICAgIHJlc3VtZShrZXksIGFyZyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXN1bWUoa2V5LCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlc3VsdCA9IGdlbltrZXldKGFyZyk7XG4gICAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgICB2YXIgd3JhcHBlZEF3YWl0ID0gdmFsdWUgaW5zdGFuY2VvZiBfQXdhaXRWYWx1ZTtcbiAgICAgIFByb21pc2UucmVzb2x2ZSh3cmFwcGVkQXdhaXQgPyB2YWx1ZS53cmFwcGVkIDogdmFsdWUpLnRoZW4oZnVuY3Rpb24gKGFyZykge1xuICAgICAgICBpZiAod3JhcHBlZEF3YWl0KSB7XG4gICAgICAgICAgcmVzdW1lKFwibmV4dFwiLCBhcmcpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldHRsZShyZXN1bHQuZG9uZSA/IFwicmV0dXJuXCIgOiBcIm5vcm1hbFwiLCBhcmcpO1xuICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICByZXN1bWUoXCJ0aHJvd1wiLCBlcnIpO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBzZXR0bGUoXCJ0aHJvd1wiLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldHRsZSh0eXBlLCB2YWx1ZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBcInJldHVyblwiOlxuICAgICAgICBmcm9udC5yZXNvbHZlKHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJ0aHJvd1wiOlxuICAgICAgICBmcm9udC5yZWplY3QodmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgZnJvbnQucmVzb2x2ZSh7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgIGRvbmU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBmcm9udCA9IGZyb250Lm5leHQ7XG5cbiAgICBpZiAoZnJvbnQpIHtcbiAgICAgIHJlc3VtZShmcm9udC5rZXksIGZyb250LmFyZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJhY2sgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2ludm9rZSA9IHNlbmQ7XG5cbiAgaWYgKHR5cGVvZiBnZW4ucmV0dXJuICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0aGlzLnJldHVybiA9IHVuZGVmaW5lZDtcbiAgfVxufVxuXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5hc3luY0l0ZXJhdG9yKSB7XG4gIF9Bc3luY0dlbmVyYXRvci5wcm90b3R5cGVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xufVxuXG5fQXN5bmNHZW5lcmF0b3IucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoYXJnKSB7XG4gIHJldHVybiB0aGlzLl9pbnZva2UoXCJuZXh0XCIsIGFyZyk7XG59O1xuXG5fQXN5bmNHZW5lcmF0b3IucHJvdG90eXBlLnRocm93ID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwidGhyb3dcIiwgYXJnKTtcbn07XG5cbl9Bc3luY0dlbmVyYXRvci5wcm90b3R5cGUucmV0dXJuID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwicmV0dXJuXCIsIGFyZyk7XG59O1xuXG5mdW5jdGlvbiBfd3JhcEFzeW5jR2VuZXJhdG9yKGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBfQXN5bmNHZW5lcmF0b3IoZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIF9hd2FpdEFzeW5jR2VuZXJhdG9yKHZhbHVlKSB7XG4gIHJldHVybiBuZXcgX0F3YWl0VmFsdWUodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBfYXN5bmNHZW5lcmF0b3JEZWxlZ2F0ZShpbm5lciwgYXdhaXRXcmFwKSB7XG4gIHZhciBpdGVyID0ge30sXG4gICAgICB3YWl0aW5nID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gcHVtcChrZXksIHZhbHVlKSB7XG4gICAgd2FpdGluZyA9IHRydWU7XG4gICAgdmFsdWUgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZShpbm5lcltrZXldKHZhbHVlKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgdmFsdWU6IGF3YWl0V3JhcCh2YWx1ZSlcbiAgICB9O1xuICB9XG5cbiAgO1xuXG4gIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yKSB7XG4gICAgaXRlcltTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgfVxuXG4gIGl0ZXIubmV4dCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGlmICh3YWl0aW5nKSB7XG4gICAgICB3YWl0aW5nID0gZmFsc2U7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHB1bXAoXCJuZXh0XCIsIHZhbHVlKTtcbiAgfTtcblxuICBpZiAodHlwZW9mIGlubmVyLnRocm93ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBpdGVyLnRocm93ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAod2FpdGluZykge1xuICAgICAgICB3YWl0aW5nID0gZmFsc2U7XG4gICAgICAgIHRocm93IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHVtcChcInRocm93XCIsIHZhbHVlKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBpbm5lci5yZXR1cm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGl0ZXIucmV0dXJuID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gcHVtcChcInJldHVyblwiLCB2YWx1ZSk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBpdGVyO1xufVxuXG5mdW5jdGlvbiBfYXN5bmNUb0dlbmVyYXRvcihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIGdlbiA9IGZuLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgICBmdW5jdGlvbiBzdGVwKGtleSwgYXJnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFyIGluZm8gPSBnZW5ba2V5XShhcmcpO1xuICAgICAgICAgIHZhciB2YWx1ZSA9IGluZm8udmFsdWU7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5mby5kb25lKSB7XG4gICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKF9uZXh0LCBfdGhyb3cpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIF9uZXh0KHZhbHVlKSB7XG4gICAgICAgIHN0ZXAoXCJuZXh0XCIsIHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gX3Rocm93KGVycikge1xuICAgICAgICBzdGVwKFwidGhyb3dcIiwgZXJyKTtcbiAgICAgIH1cblxuICAgICAgX25leHQoKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTtcbiAgICBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7XG4gICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlO1xuICAgIGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHtcbiAgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7XG4gIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufVxuXG5mdW5jdGlvbiBfZGVmaW5lRW51bWVyYWJsZVByb3BlcnRpZXMob2JqLCBkZXNjcykge1xuICBmb3IgKHZhciBrZXkgaW4gZGVzY3MpIHtcbiAgICB2YXIgZGVzYyA9IGRlc2NzW2tleV07XG4gICAgZGVzYy5jb25maWd1cmFibGUgPSBkZXNjLmVudW1lcmFibGUgPSB0cnVlO1xuICAgIGlmIChcInZhbHVlXCIgaW4gZGVzYykgZGVzYy53cml0YWJsZSA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCBkZXNjKTtcbiAgfVxuXG4gIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gICAgdmFyIG9iamVjdFN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGRlc2NzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0U3ltYm9scy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHN5bSA9IG9iamVjdFN5bWJvbHNbaV07XG4gICAgICB2YXIgZGVzYyA9IGRlc2NzW3N5bV07XG4gICAgICBkZXNjLmNvbmZpZ3VyYWJsZSA9IGRlc2MuZW51bWVyYWJsZSA9IHRydWU7XG4gICAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MpIGRlc2Mud3JpdGFibGUgPSB0cnVlO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgc3ltLCBkZXNjKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBfZGVmYXVsdHMob2JqLCBkZWZhdWx0cykge1xuICB2YXIga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGRlZmF1bHRzKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICB2YXIgdmFsdWUgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGRlZmF1bHRzLCBrZXkpO1xuXG4gICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbmZpZ3VyYWJsZSAmJiBvYmpba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgaW4gb2JqKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmpba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gX2V4dGVuZHMoKSB7XG4gIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcblxuICByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldICE9IG51bGwgPyBhcmd1bWVudHNbaV0gOiB7fTtcbiAgICB2YXIgb3duS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG93bktleXMgPSBvd25LZXlzLmNvbmNhdChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHNvdXJjZSkuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBzeW0pLmVudW1lcmFibGU7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgb3duS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gIGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7XG4gIH1cblxuICBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IHN1YkNsYXNzLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xuICBpZiAoc3VwZXJDbGFzcykgX3NldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTtcbn1cblxuZnVuY3Rpb24gX2luaGVyaXRzTG9vc2Uoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHtcbiAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzLnByb3RvdHlwZSk7XG4gIHN1YkNsYXNzLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IHN1YkNsYXNzO1xuICBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzO1xufVxuXG5mdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICBfZ2V0UHJvdG90eXBlT2YgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YgOiBmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICAgIHJldHVybiBvLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gIH07XG4gIHJldHVybiBfZ2V0UHJvdG90eXBlT2Yobyk7XG59XG5cbmZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7XG4gIF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICAgIG8uX19wcm90b19fID0gcDtcbiAgICByZXR1cm4gbztcbiAgfTtcblxuICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xufVxuXG5mdW5jdGlvbiBpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTtcbiAgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTtcblxuICB0cnkge1xuICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoRGF0ZSwgW10sIGZ1bmN0aW9uICgpIHt9KSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gIGlmIChpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSkge1xuICAgIF9jb25zdHJ1Y3QgPSBSZWZsZWN0LmNvbnN0cnVjdDtcbiAgfSBlbHNlIHtcbiAgICBfY29uc3RydWN0ID0gZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gICAgICB2YXIgYSA9IFtudWxsXTtcbiAgICAgIGEucHVzaC5hcHBseShhLCBhcmdzKTtcbiAgICAgIHZhciBDb25zdHJ1Y3RvciA9IEZ1bmN0aW9uLmJpbmQuYXBwbHkoUGFyZW50LCBhKTtcbiAgICAgIHZhciBpbnN0YW5jZSA9IG5ldyBDb25zdHJ1Y3RvcigpO1xuICAgICAgaWYgKENsYXNzKSBfc2V0UHJvdG90eXBlT2YoaW5zdGFuY2UsIENsYXNzLnByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBfY29uc3RydWN0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG59XG5cbmZ1bmN0aW9uIF93cmFwTmF0aXZlU3VwZXIoQ2xhc3MpIHtcbiAgdmFyIF9jYWNoZSA9IHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIiA/IG5ldyBNYXAoKSA6IHVuZGVmaW5lZDtcblxuICBfd3JhcE5hdGl2ZVN1cGVyID0gZnVuY3Rpb24gX3dyYXBOYXRpdmVTdXBlcihDbGFzcykge1xuICAgIGlmIChDbGFzcyA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAodHlwZW9mIENsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvblwiKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIF9jYWNoZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgaWYgKF9jYWNoZS5oYXMoQ2xhc3MpKSByZXR1cm4gX2NhY2hlLmdldChDbGFzcyk7XG5cbiAgICAgIF9jYWNoZS5zZXQoQ2xhc3MsIFdyYXBwZXIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIFdyYXBwZXIoKSB7XG4gICAgICByZXR1cm4gX2NvbnN0cnVjdChDbGFzcywgYXJndW1lbnRzLCBfZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3IpO1xuICAgIH1cblxuICAgIFdyYXBwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDbGFzcy5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBXcmFwcGVyLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBfc2V0UHJvdG90eXBlT2YoV3JhcHBlciwgQ2xhc3MpO1xuICB9O1xuXG4gIHJldHVybiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKTtcbn1cblxuZnVuY3Rpb24gX2luc3RhbmNlb2YobGVmdCwgcmlnaHQpIHtcbiAgaWYgKHJpZ2h0ICE9IG51bGwgJiYgdHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiByaWdodFtTeW1ib2wuaGFzSW5zdGFuY2VdKSB7XG4gICAgcmV0dXJuIHJpZ2h0W1N5bWJvbC5oYXNJbnN0YW5jZV0obGVmdCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxlZnQgaW5zdGFuY2VvZiByaWdodDtcbiAgfVxufVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikge1xuICByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDoge1xuICAgIGRlZmF1bHQ6IG9ialxuICB9O1xufVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHtcbiAgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkge1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgdmFyIG5ld09iaiA9IHt9O1xuXG4gICAgaWYgKG9iaiAhPSBudWxsKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpIDoge307XG5cbiAgICAgICAgICBpZiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdPYmosIGtleSwgZGVzYyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ld09ialtrZXldID0gb2JqW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgbmV3T2JqLmRlZmF1bHQgPSBvYmo7XG4gICAgcmV0dXJuIG5ld09iajtcbiAgfVxufVxuXG5mdW5jdGlvbiBfbmV3QXJyb3dDaGVjayhpbm5lclRoaXMsIGJvdW5kVGhpcykge1xuICBpZiAoaW5uZXJUaGlzICE9PSBib3VuZFRoaXMpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGluc3RhbnRpYXRlIGFuIGFycm93IGZ1bmN0aW9uXCIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vYmplY3REZXN0cnVjdHVyaW5nRW1wdHkob2JqKSB7XG4gIGlmIChvYmogPT0gbnVsbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBkZXN0cnVjdHVyZSB1bmRlZmluZWRcIik7XG59XG5cbmZ1bmN0aW9uIF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhzb3VyY2UsIGV4Y2x1ZGVkKSB7XG4gIGlmIChzb3VyY2UgPT0gbnVsbCkgcmV0dXJuIHt9O1xuICB2YXIgdGFyZ2V0ID0ge307XG4gIHZhciBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcbiAgdmFyIGtleSwgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgc291cmNlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaV07XG4gICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG5cbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBzb3VyY2VTeW1ib2xLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBrZXkgPSBzb3VyY2VTeW1ib2xLZXlzW2ldO1xuICAgICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHNvdXJjZSwga2V5KSkgY29udGludWU7XG4gICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbmZ1bmN0aW9uIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZikge1xuICBpZiAoc2VsZiA9PT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGY7XG59XG5cbmZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHtcbiAgaWYgKGNhbGwgJiYgKHR5cGVvZiBjYWxsID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgcmV0dXJuIGNhbGw7XG4gIH1cblxuICByZXR1cm4gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn1cblxuZnVuY3Rpb24gX3N1cGVyUHJvcEJhc2Uob2JqZWN0LCBwcm9wZXJ0eSkge1xuICB3aGlsZSAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgIG9iamVjdCA9IF9nZXRQcm90b3R5cGVPZihvYmplY3QpO1xuICAgIGlmIChvYmplY3QgPT09IG51bGwpIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxuZnVuY3Rpb24gX2dldCh0YXJnZXQsIHByb3BlcnR5LCByZWNlaXZlcikge1xuICBpZiAodHlwZW9mIFJlZmxlY3QgIT09IFwidW5kZWZpbmVkXCIgJiYgUmVmbGVjdC5nZXQpIHtcbiAgICBfZ2V0ID0gUmVmbGVjdC5nZXQ7XG4gIH0gZWxzZSB7XG4gICAgX2dldCA9IGZ1bmN0aW9uIF9nZXQodGFyZ2V0LCBwcm9wZXJ0eSwgcmVjZWl2ZXIpIHtcbiAgICAgIHZhciBiYXNlID0gX3N1cGVyUHJvcEJhc2UodGFyZ2V0LCBwcm9wZXJ0eSk7XG5cbiAgICAgIGlmICghYmFzZSkgcmV0dXJuO1xuICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGJhc2UsIHByb3BlcnR5KTtcblxuICAgICAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgICAgIHJldHVybiBkZXNjLmdldC5jYWxsKHJlY2VpdmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRlc2MudmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBfZ2V0KHRhcmdldCwgcHJvcGVydHksIHJlY2VpdmVyIHx8IHRhcmdldCk7XG59XG5cbmZ1bmN0aW9uIHNldCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgcmVjZWl2ZXIpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ICE9PSBcInVuZGVmaW5lZFwiICYmIFJlZmxlY3Quc2V0KSB7XG4gICAgc2V0ID0gUmVmbGVjdC5zZXQ7XG4gIH0gZWxzZSB7XG4gICAgc2V0ID0gZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCByZWNlaXZlcikge1xuICAgICAgdmFyIGJhc2UgPSBfc3VwZXJQcm9wQmFzZSh0YXJnZXQsIHByb3BlcnR5KTtcblxuICAgICAgdmFyIGRlc2M7XG5cbiAgICAgIGlmIChiYXNlKSB7XG4gICAgICAgIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGJhc2UsIHByb3BlcnR5KTtcblxuICAgICAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgICAgICBkZXNjLnNldC5jYWxsKHJlY2VpdmVyLCB2YWx1ZSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoIWRlc2Mud3JpdGFibGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocmVjZWl2ZXIsIHByb3BlcnR5KTtcblxuICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgaWYgKCFkZXNjLndyaXRhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVzYy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVjZWl2ZXIsIHByb3BlcnR5LCBkZXNjKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9kZWZpbmVQcm9wZXJ0eShyZWNlaXZlciwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzZXQodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIHJlY2VpdmVyKTtcbn1cblxuZnVuY3Rpb24gX3NldCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgcmVjZWl2ZXIsIGlzU3RyaWN0KSB7XG4gIHZhciBzID0gc2V0KHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCByZWNlaXZlciB8fCB0YXJnZXQpO1xuXG4gIGlmICghcyAmJiBpc1N0cmljdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIHNldCBwcm9wZXJ0eScpO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBfdGFnZ2VkVGVtcGxhdGVMaXRlcmFsKHN0cmluZ3MsIHJhdykge1xuICBpZiAoIXJhdykge1xuICAgIHJhdyA9IHN0cmluZ3Muc2xpY2UoMCk7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZShPYmplY3QuZGVmaW5lUHJvcGVydGllcyhzdHJpbmdzLCB7XG4gICAgcmF3OiB7XG4gICAgICB2YWx1ZTogT2JqZWN0LmZyZWV6ZShyYXcpXG4gICAgfVxuICB9KSk7XG59XG5cbmZ1bmN0aW9uIF90YWdnZWRUZW1wbGF0ZUxpdGVyYWxMb29zZShzdHJpbmdzLCByYXcpIHtcbiAgaWYgKCFyYXcpIHtcbiAgICByYXcgPSBzdHJpbmdzLnNsaWNlKDApO1xuICB9XG5cbiAgc3RyaW5ncy5yYXcgPSByYXc7XG4gIHJldHVybiBzdHJpbmdzO1xufVxuXG5mdW5jdGlvbiBfdGVtcG9yYWxSZWYodmFsLCBuYW1lKSB7XG4gIGlmICh2YWwgPT09IF90ZW1wb3JhbFVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihuYW1lICsgXCIgaXMgbm90IGRlZmluZWQgLSB0ZW1wb3JhbCBkZWFkIHpvbmVcIik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBfcmVhZE9ubHlFcnJvcihuYW1lKSB7XG4gIHRocm93IG5ldyBFcnJvcihcIlxcXCJcIiArIG5hbWUgKyBcIlxcXCIgaXMgcmVhZC1vbmx5XCIpO1xufVxuXG5mdW5jdGlvbiBfY2xhc3NOYW1lVERaRXJyb3IobmFtZSkge1xuICB0aHJvdyBuZXcgRXJyb3IoXCJDbGFzcyBcXFwiXCIgKyBuYW1lICsgXCJcXFwiIGNhbm5vdCBiZSByZWZlcmVuY2VkIGluIGNvbXB1dGVkIHByb3BlcnR5IGtleXMuXCIpO1xufVxuXG52YXIgX3RlbXBvcmFsVW5kZWZpbmVkID0ge307XG5cbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgfHwgX25vbkl0ZXJhYmxlUmVzdCgpO1xufVxuXG5mdW5jdGlvbiBfc2xpY2VkVG9BcnJheUxvb3NlKGFyciwgaSkge1xuICByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0TG9vc2UoYXJyLCBpKSB8fCBfbm9uSXRlcmFibGVSZXN0KCk7XG59XG5cbmZ1bmN0aW9uIF90b0FycmF5KGFycikge1xuICByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheShhcnIpIHx8IF9ub25JdGVyYWJsZVJlc3QoKTtcbn1cblxuZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KGFycikge1xuICByZXR1cm4gX2FycmF5V2l0aG91dEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheShhcnIpIHx8IF9ub25JdGVyYWJsZVNwcmVhZCgpO1xufVxuXG5mdW5jdGlvbiBfYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgYXJyMltpXSA9IGFycltpXTtcblxuICAgIHJldHVybiBhcnIyO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheShpdGVyKSB7XG4gIGlmIChTeW1ib2wuaXRlcmF0b3IgaW4gT2JqZWN0KGl0ZXIpIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpdGVyKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikgcmV0dXJuIEFycmF5LmZyb20oaXRlcik7XG59XG5cbmZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgdmFyIF9hcnIgPSBbXTtcbiAgdmFyIF9uID0gdHJ1ZTtcbiAgdmFyIF9kID0gZmFsc2U7XG4gIHZhciBfZSA9IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGZvciAodmFyIF9pID0gYXJyW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kID0gdHJ1ZTtcbiAgICBfZSA9IGVycjtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufVxuXG5mdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXRMb29zZShhcnIsIGkpIHtcbiAgdmFyIF9hcnIgPSBbXTtcblxuICBmb3IgKHZhciBfaXRlcmF0b3IgPSBhcnJbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmU7KSB7XG4gICAgX2Fyci5wdXNoKF9zdGVwLnZhbHVlKTtcblxuICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufVxuXG5mdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZVwiKTtcbn1cblxuZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2VcIik7XG59XG5cbmZ1bmN0aW9uIF9za2lwRmlyc3RHZW5lcmF0b3JOZXh0KGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGl0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpdC5uZXh0KCk7XG4gICAgcmV0dXJuIGl0O1xuICB9O1xufVxuXG5mdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleShrZXkpIHtcbiAgaWYgKHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIpIHtcbiAgICByZXR1cm4ga2V5O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBTdHJpbmcoa2V5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfaW5pdGlhbGl6ZXJXYXJuaW5nSGVscGVyKGRlc2NyaXB0b3IsIGNvbnRleHQpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdEZWNvcmF0aW5nIGNsYXNzIHByb3BlcnR5IGZhaWxlZC4gUGxlYXNlIGVuc3VyZSB0aGF0ICcgKyAncHJvcG9zYWwtY2xhc3MtcHJvcGVydGllcyBpcyBlbmFibGVkIGFuZCBzZXQgdG8gdXNlIGxvb3NlIG1vZGUuICcgKyAnVG8gdXNlIHByb3Bvc2FsLWNsYXNzLXByb3BlcnRpZXMgaW4gc3BlYyBtb2RlIHdpdGggZGVjb3JhdG9ycywgd2FpdCBmb3IgJyArICd0aGUgbmV4dCBtYWpvciB2ZXJzaW9uIG9mIGRlY29yYXRvcnMgaW4gc3RhZ2UgMi4nKTtcbn1cblxuZnVuY3Rpb24gX2luaXRpYWxpemVyRGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzY3JpcHRvciwgY29udGV4dCkge1xuICBpZiAoIWRlc2NyaXB0b3IpIHJldHVybjtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHtcbiAgICBlbnVtZXJhYmxlOiBkZXNjcmlwdG9yLmVudW1lcmFibGUsXG4gICAgY29uZmlndXJhYmxlOiBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSxcbiAgICB3cml0YWJsZTogZGVzY3JpcHRvci53cml0YWJsZSxcbiAgICB2YWx1ZTogZGVzY3JpcHRvci5pbml0aWFsaXplciA/IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMFxuICB9KTtcbn1cblxuZnVuY3Rpb24gX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcih0YXJnZXQsIHByb3BlcnR5LCBkZWNvcmF0b3JzLCBkZXNjcmlwdG9yLCBjb250ZXh0KSB7XG4gIHZhciBkZXNjID0ge307XG4gIE9iamVjdFsna2UnICsgJ3lzJ10oZGVzY3JpcHRvcikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgZGVzY1trZXldID0gZGVzY3JpcHRvcltrZXldO1xuICB9KTtcbiAgZGVzYy5lbnVtZXJhYmxlID0gISFkZXNjLmVudW1lcmFibGU7XG4gIGRlc2MuY29uZmlndXJhYmxlID0gISFkZXNjLmNvbmZpZ3VyYWJsZTtcblxuICBpZiAoJ3ZhbHVlJyBpbiBkZXNjIHx8IGRlc2MuaW5pdGlhbGl6ZXIpIHtcbiAgICBkZXNjLndyaXRhYmxlID0gdHJ1ZTtcbiAgfVxuXG4gIGRlc2MgPSBkZWNvcmF0b3JzLnNsaWNlKCkucmV2ZXJzZSgpLnJlZHVjZShmdW5jdGlvbiAoZGVzYywgZGVjb3JhdG9yKSB7XG4gICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjO1xuICB9LCBkZXNjKTtcblxuICBpZiAoY29udGV4dCAmJiBkZXNjLmluaXRpYWxpemVyICE9PSB2b2lkIDApIHtcbiAgICBkZXNjLnZhbHVlID0gZGVzYy5pbml0aWFsaXplciA/IGRlc2MuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMDtcbiAgICBkZXNjLmluaXRpYWxpemVyID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKGRlc2MuaW5pdGlhbGl6ZXIgPT09IHZvaWQgMCkge1xuICAgIE9iamVjdFsnZGVmaW5lJyArICdQcm9wZXJ0eSddKHRhcmdldCwgcHJvcGVydHksIGRlc2MpO1xuICAgIGRlc2MgPSBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGRlc2M7XG59XG5cbnZhciBpZCA9IDA7XG5cbmZ1bmN0aW9uIF9jbGFzc1ByaXZhdGVGaWVsZExvb3NlS2V5KG5hbWUpIHtcbiAgcmV0dXJuIFwiX19wcml2YXRlX1wiICsgaWQrKyArIFwiX1wiICsgbmFtZTtcbn1cblxuZnVuY3Rpb24gX2NsYXNzUHJpdmF0ZUZpZWxkTG9vc2VCYXNlKHJlY2VpdmVyLCBwcml2YXRlS2V5KSB7XG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY2VpdmVyLCBwcml2YXRlS2V5KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJhdHRlbXB0ZWQgdG8gdXNlIHByaXZhdGUgZmllbGQgb24gbm9uLWluc3RhbmNlXCIpO1xuICB9XG5cbiAgcmV0dXJuIHJlY2VpdmVyO1xufVxuXG5mdW5jdGlvbiBfY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHByaXZhdGVNYXApIHtcbiAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIGdldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcbiAgfVxuXG4gIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XG59XG5cbmZ1bmN0aW9uIF9jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgcHJpdmF0ZU1hcCwgdmFsdWUpIHtcbiAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHNldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcbiAgfVxuXG4gIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XG4gIHJldHVybiB2YWx1ZTtcbn0iLCJpbXBvcnQge1xuICBQb3NpdGlvbmFsQXVkaW8sXG4gIEF1ZGlvTGlzdGVuZXIsXG4gIEF1ZGlvTG9hZGVyXG59IGZyb20gJ3RocmVlJztcblxuLyoqXG4gKiBAY2xhc3MgUG9zaXRpb25hbEF1ZGlvTW9kdWxlXG4gKiBAY2F0ZWdvcnkgbW9kdWxlcy9leHRyYVxuICogQHBhcmFtIHtPYmplY3R9IFtwYXJhbXM9e2xvb3A6IHRydWV9XSAtIFRoZSBwYXJhbWV0ZXJzIG9iamVjdC5cbiAqIEBtZW1iZXJvZiBtb2R1bGU6bW9kdWxlcy9leHRyYVxuICogQGV4YW1wbGUgPGNhcHRpb24+SG93IHRvIGNyZWF0ZSBhbmQgYXBwbHkgYSBQb3NpdGlvbmFsQXVkaW9Nb2R1bGU8L2NhcHRpb24+XG4gKiBjb25zdCBmb2dNb2R1bGUgPSBjb25zdCBhdWRpb01vZHVsZSA9IG5ldyBBdWRpb01vZHVsZSh7XG4gKiAgIGxvb3A6IHRydWVcbiAqIH0pO1xuICpcbiAqIG5ldyBTcGhlcmUoe1xuICogICAuLi4sXG4gKiAgIG1vZHVsZXM6IFtcbiAqICAgICBhdWRpb01vZHVsZVxuKiAgICBdXG4gKiB9O1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb3NpdGlvbmFsQXVkaW9Nb2R1bGUge1xuICBjb25zdHJ1Y3RvcihwYXJhbXMgPSB7fSkge1xuICAgIHRoaXMucGFyYW1zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICBsb29wOiB0cnVlXG4gICAgfSwgcGFyYW1zKTtcblxuICAgIHRoaXMuYXVkaW9MaXN0ZW5lciA9IG5ldyBBdWRpb0xpc3RlbmVyKCk7XG4gICAgdGhpcy5hdWRpb0xvYWRlciA9IG5ldyBBdWRpb0xvYWRlcigpO1xuXG4gICAgdGhpcy5wb3NpdGlvbmFsQXVkaW8gPSBuZXcgUG9zaXRpb25hbEF1ZGlvKHRoaXMuYXVkaW9MaXN0ZW5lcik7XG4gICAgdGhpcy5wb3NpdGlvbmFsQXVkaW8uc2V0TG9vcCh0aGlzLnBhcmFtcy5sb29wKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGFkZExpc3RlbmVyXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIHRoZSBsaXN0ZW5lciBvZiB0aGlzIGF1ZGlvIHNvdXJjZSwgdXN1YWxseSB0aGUgY2FtZXJhLCBvcmlnaW4gb2YgdGhlIHVzZXIgcGVyc3BlY3RpdmVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgbGlzdGVuZXIgb2JqZWN0XG4gICAqIEBtZW1iZXJvZiBtb2R1bGU6bW9kdWxlcy9leHRyYS5Qb3NpdGlvbmFsQXVkaW9Nb2R1bGVcbiAgICovXG4gIGFkZExpc3RlbmVyKG9iamVjdCkge1xuICAgIG9iamVjdC5uYXRpdmUuYWRkKHRoaXMuYXVkaW9MaXN0ZW5lcik7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBwbGF5XG4gICAqIEBkZXNjcmlwdGlvbiBQbGF5cyB0aGUgZ2l2ZW4gc291bmRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gdGhlIHNvdW5kIGZpbGVcbiAgICogQG1lbWJlcm9mIG1vZHVsZTptb2R1bGVzL2V4dHJhLlBvc2l0aW9uYWxBdWRpb01vZHVsZVxuICAgKi9cbiAgcGxheShwYXRoKSB7XG4gICAgY29uc3Qgc291bmQgPSB0aGlzLnBvc2l0aW9uYWxBdWRpbztcblxuICAgIHRoaXMuYXVkaW9Mb2FkZXIubG9hZChwYXRoLCBidWZmZXIgPT4ge1xuICAgICAgc291bmQuc2V0QnVmZmVyKGJ1ZmZlcik7XG4gICAgICBzb3VuZC5zZXRSZWZEaXN0YW5jZSg1MCk7XG4gICAgICBzb3VuZC5wbGF5KCk7XG4gICAgfSk7XG4gIH1cblxuICBicmlkZ2UgPSB7XG4gICAgbWVzaChtZXNoLCBzZWxmKSB7XG4gICAgICBtZXNoLmFkZChzZWxmLnBvc2l0aW9uYWxBdWRpbyk7XG4gICAgICByZXR1cm4gbWVzaDtcbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJQb3NpdGlvbmFsQXVkaW9Nb2R1bGUiLCJwYXJhbXMiLCJtZXNoIiwic2VsZiIsImFkZCIsInBvc2l0aW9uYWxBdWRpbyIsIk9iamVjdCIsImFzc2lnbiIsImF1ZGlvTGlzdGVuZXIiLCJBdWRpb0xpc3RlbmVyIiwiYXVkaW9Mb2FkZXIiLCJBdWRpb0xvYWRlciIsIlBvc2l0aW9uYWxBdWRpbyIsInNldExvb3AiLCJsb29wIiwib2JqZWN0IiwibmF0aXZlIiwicGF0aCIsInNvdW5kIiwibG9hZCIsInNldEJ1ZmZlciIsImJ1ZmZlciIsInNldFJlZkRpc3RhbmNlIiwicGxheSJdLCJtYXBwaW5ncyI6IjtBQUFBOztBQUVBLEtB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QUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDakMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQ2pDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7RUFFakMsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsS0FBSyxFQUFFLFdBQVcsR0FBRyxFQUFFLEdBQUcsR0FBRzs7OztFQUk1QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7RUFDdEQsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ3RELElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUN0RCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7O0VBRXRELE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELFdBQVcsRUFBRSxZQUFZOztFQUV4QixJQUFJLEdBQUcsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0VBQ3hCLElBQUksR0FBRyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7O0VBRXhCLE9BQU8sU0FBUyxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sR0FBRzs7R0FFN0MsR0FBRyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztHQUMxQyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDOztHQUUxQyxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztHQUU5QixDQUFDOztFQUVGLEVBQUU7O0NBRUgsS0FBSyxFQUFFLFlBQVk7O0VBRWxCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDOUIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztFQUM5QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQzlCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7O0VBRTlCLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELElBQUksRUFBRSxZQUFZOztFQUVqQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQzdCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDN0IsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztFQUM3QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDOztFQUU3QixPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxLQUFLLEVBQUUsWUFBWTs7RUFFbEIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztFQUM5QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQzlCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDOUIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7RUFFOUIsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsV0FBVyxFQUFFLFlBQVk7O0VBRXhCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztFQUNyRSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDckUsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQ3JFLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7RUFFckUsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsTUFBTSxFQUFFLFlBQVk7O0VBRW5CLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0VBQ2xCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0VBQ2xCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0VBQ2xCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDOztFQUVsQixPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxHQUFHLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRW5CLE9BQU8sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOztFQUVqRTs7Q0FFRCxRQUFRLEVBQUUsWUFBWTs7RUFFckIsT0FBTyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7O0VBRTdFOztDQUVELE1BQU0sRUFBRSxZQUFZOztFQUVuQixPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7O0VBRTFGOztDQUVELGVBQWUsRUFBRSxZQUFZOztFQUU1QixPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDOztFQUV6Rjs7Q0FFRCxTQUFTLEVBQUUsWUFBWTs7RUFFdEIsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDOztFQUUxQzs7Q0FFRCxTQUFTLEVBQUUsV0FBVyxNQUFNLEdBQUc7O0VBRTlCLE9BQU8sSUFBSSxDQUFDLGNBQWMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7O0VBRXJEOztDQUVELElBQUksRUFBRSxXQUFXLENBQUMsRUFBRSxLQUFLLEdBQUc7O0VBRTNCLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDO0VBQ25DLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDO0VBQ25DLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDO0VBQ25DLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDOztFQUVuQyxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxXQUFXLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssR0FBRzs7RUFFdkMsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxjQUFjLEVBQUUsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDOztFQUVuRTs7Q0FFRCxNQUFNLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRXRCLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFLEdBQUc7O0VBRWhHOztDQUVELFNBQVMsRUFBRSxXQUFXLEtBQUssRUFBRSxNQUFNLEdBQUc7O0VBRXJDLEtBQUssTUFBTSxLQUFLLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDOztFQUV2QyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQztFQUN6QixJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDN0IsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQzdCLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzs7RUFFN0IsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsT0FBTyxFQUFFLFdBQVcsS0FBSyxFQUFFLE1BQU0sR0FBRzs7RUFFbkMsS0FBSyxLQUFLLEtBQUssU0FBUyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7RUFDdEMsS0FBSyxNQUFNLEtBQUssU0FBUyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUM7O0VBRXZDLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0VBQ3pCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztFQUM3QixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7RUFDN0IsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOztFQUU3QixPQUFPLEtBQUssQ0FBQzs7RUFFYjs7Q0FFRCxtQkFBbUIsRUFBRSxXQUFXLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUUxRCxLQUFLLE1BQU0sS0FBSyxTQUFTLEdBQUc7O0dBRTNCLE9BQU8sQ0FBQyxJQUFJLEVBQUUscUVBQXFFLEVBQUUsQ0FBQzs7R0FFdEY7O0VBRUQsSUFBSSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0VBQ2pDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztFQUNqQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7RUFDakMsSUFBSSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDOztFQUVqQyxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7QUFhSixTQUFTLGlCQUFpQixFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxHQUFHOztDQUVwRCxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQzs7Q0FFakMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7Q0FDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7O0NBRXJCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUM7Q0FDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7O0NBRXpCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUM7O0NBRW5ELE9BQU8sR0FBRyxPQUFPLElBQUksRUFBRSxDQUFDOztDQUV4QixLQUFLLE9BQU8sQ0FBQyxTQUFTLEtBQUssU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDOztDQUV4RSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7O0NBRTNMLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsS0FBSyxTQUFTLEdBQUcsT0FBTyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7Q0FDbEYsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztDQUN4RixJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLEtBQUssU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDOztDQUVyRjs7QUFFRCxNQUFNLENBQUMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUMsU0FBUyxFQUFFOztDQUV0RSxtQkFBbUIsRUFBRSxJQUFJOztDQUV6QixPQUFPLEVBQUUsV0FBVyxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUVuQyxLQUFLLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssTUFBTSxHQUFHOztHQUVyRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztHQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzs7R0FFckIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDOztHQUVmOztFQUVELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO0VBQ3pDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDOztFQUV4Qzs7Q0FFRCxLQUFLLEVBQUUsWUFBWTs7RUFFbEIsT0FBTyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0VBRTNDOztDQUVELElBQUksRUFBRSxXQUFXLE1BQU0sR0FBRzs7RUFFekIsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO0VBQzFCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzs7RUFFNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDOztFQUV0QyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7O0VBRXRDLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQztFQUN0QyxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7RUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDOztFQUV4QyxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxPQUFPLEVBQUUsWUFBWTs7RUFFcEIsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDOztFQUUxQzs7Q0FFRCxFQUFFLENBQUM7Ozs7OztBQU1KLFNBQVMscUJBQXFCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEdBQUc7O0NBRXhELGlCQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQzs7Q0FFdkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7Q0FDeEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQzs7Q0FFM0I7O0FBRUQscUJBQXFCLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDL0UscUJBQXFCLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxxQkFBcUIsQ0FBQzs7QUFFcEUscUJBQXFCLENBQUMsU0FBUyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQzs7Ozs7Ozs7O0FBUy9ELFNBQVMsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRzs7Q0FFakMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ2pCLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztDQUNqQixJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Q0FDakIsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxTQUFTLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzs7Q0FFdEM7O0FBRUQsTUFBTSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUU7O0NBRTFCLEtBQUssRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRzs7RUFFakMsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRXBDOztDQUVELFNBQVMsRUFBRSxXQUFXLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUMsR0FBRzs7OztFQUk3RSxJQUFJLEVBQUUsR0FBRyxJQUFJLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRTtHQUM5QixFQUFFLEdBQUcsSUFBSSxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUU7R0FDM0IsRUFBRSxHQUFHLElBQUksRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFO0dBQzNCLEVBQUUsR0FBRyxJQUFJLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRTs7R0FFM0IsRUFBRSxHQUFHLElBQUksRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFO0dBQzNCLEVBQUUsR0FBRyxJQUFJLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRTtHQUMzQixFQUFFLEdBQUcsSUFBSSxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUU7R0FDM0IsRUFBRSxHQUFHLElBQUksRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0VBRTdCLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRzs7R0FFdkQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7O0lBRVosR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFOztJQUUzQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUU7SUFDNUIsTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOzs7R0FHeEIsS0FBSyxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sR0FBRzs7SUFFOUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUU7S0FDNUIsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQzs7SUFFcEMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztJQUM5QixDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDOztJQUU5Qjs7R0FFRCxJQUFJLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDOztHQUVuQixFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0dBQ3hCLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7R0FDeEIsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztHQUN4QixFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDOzs7R0FHeEIsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRzs7SUFFbEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDOztJQUUvRCxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ1IsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNSLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDUixFQUFFLElBQUksQ0FBQyxDQUFDOztJQUVSOztHQUVEOztFQUVELEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDdEIsR0FBRyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDMUIsR0FBRyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDMUIsR0FBRyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7O0VBRTFCOztDQUVELEVBQUUsQ0FBQzs7QUFFSixNQUFNLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFBRTs7Q0FFOUMsQ0FBQyxFQUFFOztFQUVGLEdBQUcsRUFBRSxZQUFZOztHQUVoQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7O0dBRWY7O0VBRUQsR0FBRyxFQUFFLFdBQVcsS0FBSyxHQUFHOztHQUV2QixJQUFJLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztHQUNoQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7R0FFeEI7O0VBRUQ7O0NBRUQsQ0FBQyxFQUFFOztFQUVGLEdBQUcsRUFBRSxZQUFZOztHQUVoQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7O0dBRWY7O0VBRUQsR0FBRyxFQUFFLFdBQVcsS0FBSyxHQUFHOztHQUV2QixJQUFJLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztHQUNoQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7R0FFeEI7O0VBRUQ7O0NBRUQsQ0FBQyxFQUFFOztFQUVGLEdBQUcsRUFBRSxZQUFZOztHQUVoQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7O0dBRWY7O0VBRUQsR0FBRyxFQUFFLFdBQVcsS0FBSyxHQUFHOztHQUV2QixJQUFJLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztHQUNoQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7R0FFeEI7O0VBRUQ7O0NBRUQsQ0FBQyxFQUFFOztFQUVG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QUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztHQUV0QyxNQUFNLEtBQUssS0FBSyxLQUFLLEtBQUssR0FBRzs7R0FFN0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7R0FFdEMsTUFBTSxLQUFLLEtBQUssS0FBSyxLQUFLLEdBQUc7O0dBRTdCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7O0dBRXRDLE1BQU0sS0FBSyxLQUFLLEtBQUssS0FBSyxHQUFHOztHQUU3QixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztHQUV0QyxNQUFNLEtBQUssS0FBSyxLQUFLLEtBQUssR0FBRzs7R0FFN0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7R0FFdEMsTUFBTSxLQUFLLEtBQUssS0FBSyxLQUFLLEdBQUc7O0dBRTdCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDdEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7O0dBRXRDOztFQUVELEtBQUssTUFBTSxLQUFLLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7RUFFaEQsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsZ0JBQWdCLEVBQUUsV0FBVyxJQUFJLEVBQUUsS0FBSyxHQUFHOzs7Ozs7RUFNMUMsSUFBSSxTQUFTLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsQ0FBQzs7RUFFckQsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztFQUNyQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0VBQ3JCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7RUFDckIsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDOztFQUVoQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7RUFFeEIsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQscUJBQXFCLEVBQUUsV0FBVyxDQUFDLEdBQUc7Ozs7OztFQU1yQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUTs7R0FFbEIsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0dBQzNDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtHQUMzQyxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUU7O0dBRTVDLEtBQUssR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7R0FDdkIsQ0FBQyxDQUFDOztFQUVILEtBQUssS0FBSyxHQUFHLENBQUMsR0FBRzs7R0FFaEIsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssR0FBRyxHQUFHLEVBQUUsQ0FBQzs7R0FFbkMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0dBQ25CLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQztHQUM1QixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUM7R0FDNUIsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDOztHQUU1QixNQUFNLEtBQUssR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHOztHQUVwQyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7O0dBRTdDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQztHQUM1QixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7R0FDbkIsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDO0dBQzVCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQzs7R0FFNUIsTUFBTSxLQUFLLEdBQUcsR0FBRyxHQUFHLEdBQUc7O0dBRXZCLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQzs7R0FFN0MsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDO0dBQzVCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQztHQUM1QixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7R0FDbkIsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDOztHQUU1QixNQUFNOztHQUVOLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQzs7R0FFN0MsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDO0dBQzVCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQztHQUM1QixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUM7R0FDNUIsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDOztHQUVuQjs7RUFF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QUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7RUFDekQsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7RUFDekQsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7RUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDOztFQUV6RCxPQUFPLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRTlCOztDQUVELGVBQWUsRUFBRSxXQUFXLENBQUMsR0FBRzs7RUFFL0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztFQUN2QyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7O0VBSTNDLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxH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LEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7RUFDNUQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQztFQUM1RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO0VBQzdELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7O0VBRTdELE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELFFBQVEsRUFBRSxZQUFZOztFQUVyQixJQUFJLENBQUMsR0FBRzs7R0FFUCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ1YsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUNWLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDVixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUVWLENBQUM7O0VBRUYsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsS0FBSyxFQUFFLFlBQVk7O0VBRWxCLE9BQU8sSUFBSSxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDOztFQUVoRDs7Q0FFRCxJQUFJLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRXBCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDdkIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQzs7RUFFcEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUMzRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzNFLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7RUFDL0UsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVB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RUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFekMsS0FBSyxLQUFLLENBQUMsS0FBSyxLQUFLLEtBQUssR0FBRzs7R0FFNUIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFbkQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDaEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNsQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDOztHQUVaLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7R0FDdEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFbEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0dBQ3RCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUN0QixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFakIsTUFBTSxLQUFLLEtBQUssQ0FBQyxLQUFLLEtBQUssS0FBSyxHQUFHOztHQUVuQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVuRCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7R0FDdEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0dBQ3RCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7O0dBRWQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0dBQ3RCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUN0QixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFakIsTUFBTSxLQUFLLEtBQUssQ0FBQyxLQUFLLEtBQUssS0FBSyxHQUFHOztHQUVuQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVuRCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7R0FDdEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNsQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDbEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUNaLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVqQixNQUFNLEtBQUssS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLLEdBQUc7O0dBRW5DLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7O0dBRW5ELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ2hCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ2hCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztHQUNkLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ2hCLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVqQixNQUFNLEtBQUssS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLLEdBQUc7O0dBRW5DLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7O0dBRW5ELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ2hCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7R0FDWixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDOztHQUVsQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ2xCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztHQUN0QixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7O0dBRXZCLE1BQU0sS0FBSyxLQUFLLENBQUMsS0FBSyxLQUFLLEtBQUssR0FBRzs7R0FFbkMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFbkQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDaEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0dBQ2QsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7O0dBRWhCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7O0dBRXRCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztHQUN0QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUNoQixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7O0dBRXZCOzs7RUFHRCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0VBQ1osRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztFQUNaLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7OztFQUdiLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7RUFDYixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0VBQ2IsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztFQUNiLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7O0VBRWIsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsMEJBQTBCLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRTFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7O0VBRXZCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7RUFDM0MsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztFQUN2QyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0VBQzFDLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7RUFDMUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs7RUFFMUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7RUFDMUIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDbEIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7O0VBRWxCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0VBQ2xCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO0VBQzFCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztFQUVsQixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztF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R0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7RUFFakUsSUFBSSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0VBQ2hFLElBQUksR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztFQUNoRSxJQUFJLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7RUFDakUsSUFBSSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztFQUVqRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN4RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN4RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN4RCxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzs7RUFFekQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7RUFDeEQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7RUFDeEQsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7RUFDeEQsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7O0VBRXpELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQ3hELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQ3hELEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQ3pELEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOztFQUV6RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN4RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN4RCxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUN6RCxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzs7RUFFekQsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsY0FBYyxFQUFFLFdBQVcsQ0FBQyxHQUFHOztFQUU5QixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDOztFQUV2QixFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0VBQ3hELEVBQUUsRUFBRSxD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RztPQUNkLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztJQUNsQjtHQUNELEdBQUc7SUFDRixFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNkLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztJQUNsQjtHQUNELEdBQUc7SUFDRixFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNkLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztJQUNsQjtHQUNELEdBQUc7SUFDRixFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNkLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztPQUNmLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztJQUNsQjs7SUFFQTs7RUFFRjs7Q0FFRCxTQUFTLEVBQUUsWUFBWTs7RUFFdEIsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztFQUN2QixJQUFJLEdBQUcsQ0FBQzs7RUFFUixHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7RUFDaEQsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO0VBQ2hELEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQzs7RUFFaEQsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO0VBQ2xELEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQztFQUNsRCxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7O0VBRXBELE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELFdBQVcsRUFBRSxXQUFXLENBQUMsR0FBRzs7RUFFM0IsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFdkIsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDZixFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNmLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOztFQUVmLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELFVBQVUsRUFBRSxXQUFXLENBQUMsRUFBRSxpQkFBaUIsR0FBRzs7O0VBRzdDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRO0dBQ3JCLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUTs7R0FFZixHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtHQUMxRCxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtHQUMxRCxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTtHQUM1RCxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTs7R0FFOUQsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztHQUMvRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHO0dBQy9HLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7R0FDL0csR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOztFQUVqSCxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOztFQUV4RCxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUc7O0dBRWhCLElBQUksR0FBRyxHQUFHLG1FQUFtRSxDQUFDOztHQUU5RSxLQUFLLGlCQUFpQixLQUFLLElBQUksR0FBRzs7SUFFakMsTUFBTSxJQUFJLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzs7SUFFdkIsTUFBTTs7SUFFTixPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDOztJQUVwQjs7R0FFRCxPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQzs7R0FFdkI7O0VBRUQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQzs7RUFFckIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7RUFDdkIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDO0VBQ2pJLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQztFQUNqSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7O0VBRWpJLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0VBQ3ZCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQztFQUNqSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7RUFDakksRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDOztFQUVqSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztFQUN2QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7RUFDakksRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDO0VBQ2xJLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQzs7RUFFbEksRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7RUFDeEIsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDO0VBQ2xJLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQztFQUNsSSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7O0VBRWxJLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELEtBQUssRUFBRSxXQUFXLENBQUMsR0FBRzs7RUFFckIsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztFQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOztFQUU5QixFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7RUFDekMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0VBQ3pDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztFQUMxQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7O0VBRTFDLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELGlCQUFpQixFQUFFLFlBQVk7O0VBRTlCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7O0VBRXZCLElBQUksUUFBUSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ3pFLElBQUksUUFBUSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ3pFLElBQUksUUFBUSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztFQUUzRSxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUM7O0VBRTdE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QUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7R0FDN0MsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0dBQzdDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7R0FDaEQsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFVixDQUFDOztHQUVELE9BQU8sSUFBSSxDQUFDOztFQUViOztDQUVELFNBQVMsRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHOztFQUUvQixJQUFJLENBQUMsR0FBRzs7R0FFUCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ1YsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUNWLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDVixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUVWLENBQUM7O0VBRUYsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsU0FBUyxFQUFFLFdBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUc7O0VBRS9CLElBQUksQ0FBQyxHQUFHOztHQUVQLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDVixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ1YsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUNWLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0dBRVYsQ0FBQzs7RUFFRixPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxPQUFPLEVBQUUsV0FBVyxRQUFRLEVBQUUsVUFBVSxFQUFFLEtBQUssR0FBRzs7RUFFakQsSUFBSSxDQUFDLDBCQUEwQixFQUFFLFVBQVUsRUFBRSxDQUFDO0VBQzlDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7RUFDcEIsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsQ0FBQzs7RUFFN0IsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsU0FBUyxFQUFFLFlBQVk7O0VBRXRCLElBQUksTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7RUFDM0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7RUFFM0IsT0FBTyxTQUFTLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLEtBQUssR0FBRzs7R0FFeEQsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7R0FFdkIsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0dBQzFELElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztHQUMxRCxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7OztHQUczRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7R0FDN0IsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQzs7R0FFekIsUUFBUSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7R0FDdEIsUUFBUSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7R0FDdEIsUUFBUSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7OztHQUd0QixNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDOztHQUVwQixJQUFJLEtBQUssR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0dBQ25CLElBQUksS0FBSyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7R0FDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs7R0FFbkIsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUM7R0FDOUIsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUM7R0FDOUIsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUM7O0dBRTlCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksS0FBSyxDQUFDO0dBQzlCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksS0FBSyxDQUFDO0dBQzlCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksS0FBSyxDQUFDOztHQUU5QixNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQztHQUM5QixNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQztHQUM5QixNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxJQUFJLEtBQUssQ0FBQzs7R0FFL0IsVUFBVSxDQUFDLHFCQUFxQixFQUFFLE1BQU0sRUFBRSxDQUFDOztHQUUzQyxLQUFLLENB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O0VBQzdCLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLE1BQU0sS0FBSyxDQUFDLENBQUM7RUFDN0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQzs7RUFFM0IsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztFQUMxRCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0VBQzFELEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztFQUM3RCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDOztFQUVyRCxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxNQUFNLEVBQUUsV0FBVyxNQUFNLEdBQUc7O0VBRTNCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDdkIsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQzs7RUFFekIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFL0IsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLE9BQU8sS0FBSyxDQUFDOztHQUV4Qzs7RUFFRCxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxTQUFTLEVBQUUsV0FBVyxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUVyQyxLQUFLLE1BQU0sS0FBSyxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzs7RUFFdkMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFL0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDOztHQUV6Qzs7RUFFRCxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxPQUFPLEVBQUUsV0FBVyxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUVuQyxLQUFLLEtBQUssS0FBSyxTQUFTLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztFQUN0QyxLQUFLLE1BQU0sS0FBSyxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzs7RUFFdkMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFdkIsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUMxQixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUM5QixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUM5QixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRTlCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzlCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzlCLEtBQUssRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0VBQ2hDLEtBQUssRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztFQUVoQyxLQUFLLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztFQUNoQyxLQUFLLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztFQUNoQyxLQUFLLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztFQUNoQyxLQUFLLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7RUFFaEMsT0FBTyxLQUFLLENBQUM7O0VBRWI7O0NBRUQsRUFBRSxDQUFDOzs7Ozs7QUFNSixT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QUFFLENBQUMsRUFBRSxDQUFDLEdBQUc7O0dBRTNCLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQ3BCLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQ3BCLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDOUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztHQUMxQixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztHQUMxRCxPQUFPLENBQUMsQ0FBQzs7R0FFVDs7RUFFRCxPQUFPLFNBQVMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHOzs7R0FHakMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ2xDLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDM0IsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFM0IsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHOztJQUVkLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7SUFFN0IsTUFBTTs7SUFFTixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDckQsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7SUFFdEIsSUFBSSxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQ3BDLElBQUksQ0FBQyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDNUIsSUFBSSxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOztJQUVwQzs7R0FFRCxPQUFPLElBQUksQ0FBQzs7R0FFWixDQUFDOztFQUVGLEVBQUU7O0NBRUgsUUFBUSxFQUFFLFdBQVcsS0FBSyxHQUFHOztFQUU1QixTQUFTLFdBQVcsRUFBRSxNQUFNLEdBQUc7O0dBRTlCLEtBQUssTUFBTSxLQUFLLFNBQVMsR0FBRyxPQUFPOztHQUVuQyxLQUFLLFVBQVUsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUc7O0lBRS9CLE9BQU8sQ0FBQyxJQUFJLEVBQUUsa0NBQWtDLEdBQUcsS0FBSyxHQUFHLG1CQUFtQixFQUFFLENBQUM7O0lBRWpGOztHQUVEOzs7RUFHRCxJQUFJLENBQUMsQ0FBQzs7RUFFTixLQUFLLENBQUMsR0FBRyxpQ0FBaUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUc7Ozs7R0FJMUQsSUFBSSxLQUFLLENBQUM7R0FDVixJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDbEIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV4QixTQUFTLElBQUk7O0lBRVosS0FBSyxLQUFLLENBQUM7SUFDWCxLQUFLLE1BQU07O0tBRVYsS0FBSyxLQUFLLEdBQUcsK0RBQStELENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHOzs7TUFHakcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO01BQzNELElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQztNQUMzRCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7O01BRTNELFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7TUFFMUIsT0FBTyxJQUFJLENBQUM7O01BRVo7O0tBRUQsS0FBSyxLQUFLLEdBQUcscUVBQXFFLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHOzs7TUFHdkcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO01BQzNELElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQztNQUMzRCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7O01BRTNELFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7TUFFMUIsT0FBTyxJQUFJLENBQUM7O01BRVo7O0tBRUQsTUFBTTs7SUFFUCxLQUFLLEtBQUssQ0FBQztJQUNYLEtBQUssTUFBTTs7S0FFVixLQUFLLEtBQUssR0FBRywrRUFBK0UsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEdBQUc7OztNQUdqSCxJQUFJLENBQUMsR0FBRyxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO01BQ3ZDLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO01BQ3pDLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDOztNQUV6QyxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O01BRTFCLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztNQUU5Qjs7S0FFRCxNQUFNOztJQUVQOztHQUVELE1BQU0sS0FBSyxDQUFDLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHOzs7O0dBSXBELElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUNqQixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDOztHQUV0QixLQUFLLElBQUksS0FBSyxDQUFDLEdBQUc7OztJQUdqQixJQUFJLENBQUMsQ0FBQyxHQUFHLFFBQVEsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBQ2pFLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7SUFDakUsSUFBSSxDQUFDLENBQUMsR0FBRyxRQUFRLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQzs7SUFFakUsT0FBTyxJQUFJLENBQUM7O0lBRVosTUFBTSxLQUFLLElBQUksS0FBSyxDQUFDLEdBQUc7OztJQUd4QixJQUFJLENBQUMsQ0FBQyxHQUFHLFFBQVEsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBQ2pFLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUM7SUFDakUsSUFBSSxDQUFDLENBQUMsR0FBRyxRQUFRLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQzs7SUFFakUsT0FBTyxJQUFJLENBQUM7O0lBRVo7O0dBRUQ7O0VBRUQsS0FBSyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUc7OztHQUdoQyxJQUFJLEdBQUcsR0FBRyxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUM7O0dBRWpDLEtBQUssR0FBRyxLQUFLLFNBQVMsR0FBRzs7O0lBR3hCLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUM7O0lBRW5CLE1BQU07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LEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUVoRCxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7RUFDNUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQzVDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzs7RUFFNUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQzVDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUM1QyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7O0VBRTVDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztFQUM1QyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7RUFDNUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOztFQUU1QyxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxjQUFjLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRTlCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7O0VBRXZCLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztFQUN6QyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7RUFDekMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDOztFQUV6QyxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxXQUFXLEVBQUUsWUFBWTs7RUFFeEIsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFdkIsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUU7R0FDeEMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0dBQ3JDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUV2QyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztFQUU3RTs7Q0FFRCxVQUFVLEVBQUUsV0FBVyxNQUFNLEVBQUUsaUJBQWlCLEdBQUc7O0VBRWxELEtBQUssTUFBTSxJQUFJLE1BQU0sQ0FBQyxTQUFTLEdBQUc7O0dBRWpDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsOERBQThELEVBQUUsQ0FBQzs7R0FFaEY7O0VBRUQsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVE7R0FDdkIsRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFROztHQUVsQixHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUU7R0FDM0MsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0dBQzNDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTs7R0FFM0MsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7R0FDM0IsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7R0FDM0IsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7O0dBRTNCLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQzs7RUFFekMsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHOztHQUVoQixJQUFJLEdBQUcsR0FBRyxtRUFBbUUsQ0FBQzs7R0FFOUUsS0FBSyxpQkFBaUIsS0FBSyxJQUFJLEdBQUc7O0lBRWpDLE1BQU0sSUFBSSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7O0lBRXZCLE1BQU07O0lBRU4sT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQzs7SUFFcEI7O0dBRUQsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7O0dBRXZCOztFQUVELElBQUksTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7O0VBRXJCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0VBQ3ZCLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7RUFDN0MsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQzs7RUFFN0MsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7RUFDdkIsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLE1BQU0sQ0FBQztFQUM3QyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDOztFQUU3QyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztFQUN2QixFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssTUFBTSxDQUFDO0VBQzdDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7O0VBRTdDLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELFNBQVMsRUFBRSxZQUFZOztFQUV0QixJQUFJLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFM0IsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO0VBQzVDLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztFQUM1QyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7O0VBRTVDLE9BQU8sSUFBSSxDQUFDOztFQUVaOztDQUVELGVBQWUsRUFBRSxXQUFXLE9BQU8sR0FBRzs7RUFFckMsT0FBTyxJQUFJLENBQUMsY0FBYyxFQUFFLE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQzs7RUFFckU7O0NBRUQsa0JBQWtCLEVBQUUsV0FBVyxDQUFDLEdBQUc7O0VBRWxDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7O0VBRXRCLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDaEIsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNoQixDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2hCLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDaEIsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNoQixDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2hCLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDaEIsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNoQixDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUVoQixPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxNQUFNLEVBQUUsV0FBVyxNQUFNLEdBQUc7O0VBRTNCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDdkIsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQzs7RUFFekIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFOUIsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLE9BQU8sS0FBSyxDQUFDOztHQUV4Qzs7RUFFRCxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxTQUFTLEVBQUUsV0FBVyxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUVyQyxLQUFLLE1BQU0sS0FBSyxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzs7RUFFdkMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFOUIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDOztHQUV6Qzs7RUFFRCxPQUFPLElBQUksQ0FBQzs7RUFFWjs7Q0FFRCxPQUFPLEVBQUUsV0FBVyxLQUFLLEVBQUUsTUFBTSxHQUFHOztFQUVuQyxLQUFLLEtBQUssS0FBSyxTQUFTLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztFQUN0QyxLQUFLLE1BQU0sS0FBSyxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzs7RUFFdkMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFdkIsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUMxQixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUM5QixLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRTlCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzlCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzlCLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUU5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QUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUMvRCxJQUFJLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDL0QsSUFBSSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0VBQ25FLElBQUksSUFBSSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7RUFFdkUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxHQUFHLEdBQUcsRUFBRSxJQUFJLEdBQUcsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7RUFDdkYsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxHQUFHLEdBQUcsRUFBRSxJQUFJLEdBQUcsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7RUFDdkYsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUs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ekIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFOUIsSUFBSSxLQUFLLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDOztJQUV4QixFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzs7SUFFbEQsSUFBSSxFQUFFLEdBQUcsS0FBSyxD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QUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDOztNQUUvQzs7S0FFRCxNQUFNOztLQUVOLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxHQUFHOzs7O01BSXJCLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxHQUFHLFNBQVMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDO01BQ2pELEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUM7TUFDckYsT0FBTyxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7O01BRS9DLE1BQU0sS0FBSyxFQUFFLElBQUksTUFBTSxHQUFHOzs7O01BSTFCLEVBQUUsR0FBRyxDQUFDLENBQUM7TUFDUCxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUM7TUFDMUQsT0FBTyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQzs7TUFFbkMsTUFBTTs7OztNQUlOLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLEdBQUcsR0FBRyxTQUFTLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQztNQUMvQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxLQUFLLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFB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RUFBRSxjQUFjLEdBQUc7O0VBRTlDLElBQUksSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7O0VBRTNDLElBQUksT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7R0FDakMsT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7R0FDOUIsT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQzs7RUFFaEMsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7RUFFekIsS0FBSyxPQUFPLElBQUksQ0FBQyxHQUFHOztHQUVuQixJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQztHQUMxQyxJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQzs7R0FFMUMsTUFBTTs7R0FFTixJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQztHQUMxQyxJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQzs7R0FFMUM7O0VBRUQsS0FBSyxPQUFPLElBQUksQ0FBQyxHQUFHOztHQUVuQixLQUFLLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQztHQUMzQyxLQUFLLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQzs7R0FFM0MsTUFBTTs7R0FFTixLQUFLLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQztHQUMzQyxLQUFLLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQzs7R0FFM0M7O0VBRUQsS0FBSyxFQUFFLElBQUksR0FBRyxLQUFLLFFBQVEsS0FBSyxHQUFHLElBQUksRUFBRSxHQUFHLE9BQU8sSUFBSSxDQUFDOzs7OztFQUt4RCxLQUFLLEtBQUssR0FBRyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDOztFQUVsRCxLQUFLLEtBQUssR0FBRyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDOztFQUVsRCxLQUFLLE9BQU8sSUFBSSxDQUFDLEdBQUc7O0dBRW5CLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDO0dBQzNDLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDOztHQUUzQyxNQUFNOztHQUVOLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDO0dBQzNDLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDOztHQUUzQzs7RUFFRCxLQUFLLEVBQUUsSUFBSSxHQUFHLEtBQUssUUFBUSxLQUFLLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxJQUFJLENBQUM7O0VBRXhELEtBQUssS0FBSyxHQUFHLElBQUksSUFBSSxJQUFJLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUM7O0VBRWxELEtB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LEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztHQUU5QyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsT0FBTyxHQUFHOztJQUVoQyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2pDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7O0lBRWpDLE1BQU07O0lBRU4sSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ25DLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDOztJQUVaOztHQUVELE1BQU0sS0FBSyxLQUFLLEtBQUssS0FBSyxHQUFHOztHQUU3QixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztHQUU1QyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsT0FBTyxHQUFHOztJQUVoQyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDbkMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztJQUVuQyxNQUFNOztJQUVOLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1osSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7SUFFakM7O0dBRUQsTUFBTSxLQUFLLEtBQUssS0FBSyxLQUFLLEdBQUc7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QUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7O0VBRXZELElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztFQUNyQixJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7RUFDakIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDOztFQUVsQixNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRzs7R0FFOUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7O0dBRTdGLEtBQUssT0FBTyxLQUFLLFNBQVMsR0FBRzs7SUFFNUIsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFcEY7O0dBRUQsS0FBSyxNQUFNLEtBQUssU0FBUyxHQUFHOztJQUUzQixLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFaEY7O0dBRUQsS0FBSyxHQUFHLEtBQUssU0FBUyxHQUFHOztJQUV4QixPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFdEQ7O0dBRUQsS0FBSyxJQUFJLEtBQUssU0FBUyxHQUFHOztJQUV6QixRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFekQ7O0dBRUQ7O0VBRUQsU0FBUyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxHQUFHOztHQUUxQyxJQUFJLGFBQWEsR0FBRyxPQUFPLEtBQUssU0FBUyxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDbEksSUFBSSxZQUFZLEdBQUcsTUFBTSxLQUFLLFNBQVMsR0FBRyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDOztHQUVuSSxJQUFJLElBQUksR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxDQUFDOztHQUU1RSxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7R0FFekIsS0FBSyxHQUFHLEtBQUssU0FBUyxHQUFHOztJQUV4QixLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFdEc7O0dBRUQsS0FBSyxJQUFJLEtBQUssU0FBUyxHQUFHOztJQUV6QixLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQzs7SUFFekc7O0dBRUQ7O0VBRUQsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQzs7RUFFN0IsS0FBSyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRzs7R0FFeEIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0lBRTFDLElBQUksS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFeEIsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztJQUN4QixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDOztJQUV4QixNQUFNLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxFQUFFLEdBQUcsS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUc7O0tBRXpELEtBQUssT0FBTyxLQUFLLFNBQVMsR0FBRzs7TUFFNUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE9BQU8s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LEVBQUUsQ0FBQztFQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztFQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztFQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztFQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQztFQUN4QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztFQUN4QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQzs7OztFQUkzQixJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7Ozs7RUFJeEIsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQzs7RUFFL0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRWpELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDOztHQUU1Qzs7OztFQUlELElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7O0VBRTNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUUvQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQzs7R0FFeEM7Ozs7RUFJRCxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDOztFQUV6QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFOUMsSUFBSSxDQUFDLEtBQUssQ0FB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R0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0tBRXRFLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQzs7S0FFM0U7O0lBRUQ7O0dBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7O0dBRXRDOzs7O0VBSUQsSUFBSSxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQzs7RUFFckMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRXBELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDOztHQUVsRDs7OztFQUlELElBQUksV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUM7O0VBRXJDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUVwRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQzs7R0FFbEQ7Ozs7RUFJRCxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDOztFQUV6QyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFdEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0dBRTlDOzs7O0VBSUQsSUFBSSxXQUFXLEdB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RSxDQUFDLENBQUMsQ0FBQztNQUN0QixPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7TUFDMUIsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDOztNQUUxQixPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztNQUN0QixPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7TUFDMUIsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDOztNQUUxQixPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztNQUN0QixPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7TUFDMUIsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDOztNQUUxQjs7S0FFRDs7SUFFRCxNQUFNOzs7O0lBSU4sTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHOztLQUV4RCxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztLQUM3QixFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7S0FDakMsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOztLQUVqQyxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztLQUN4QixFQUFFLENBQUMsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztLQUN4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Q0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7RUFFeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztFQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDOztFQUU3QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0VBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7RUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzs7RUFFL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7RUFFakMsS0FBSyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7O0VBRTVFLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQzs7RUFFekMsT0FBTyxJQUFJLENBQUM7O0VBRVo7O0NBRUQsRUFBRSxDQUFDOzs7Ozs7O0FBT0osU0FBUyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsR0FBRzs7Q0FFbEUsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7Q0FFcEIsSUFBSSxDQUFDLElBQUksR0FBRyxvQkFBb0IsQ0FBQzs7Q0FFakMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7Q0FDZCxJQUFJLENBQUMsSUFBSSxH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LEtBQUssQ0FBQyxDQUFDOztFQUV4QyxJQUFJLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0VBQ25CLElBQUksS0FBSyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDcEIsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztFQUNsQixJQUFJLE1BQU0sR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDOztFQUVyQixLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHOztHQUV6QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7R0FDbEUsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0dBQ3BFLElBQUksTUFBTSxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0dBQzFELElBQUksTUFBTSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDOztHQUUzRCxJQUFJLElBQUksTUFBTSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssRUFBRSxDQUFDO0dBQy9DLEtBQUssR0FBRyxJQUFJLEdBQUcsTUFBTSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDO0dBQ3BELEdBQUcsSUFBSSxNQUFNLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxFQUFFLENBQUM7R0FDOUMsTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFNLEtBQUssSUFBSSxDQUFDLElB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QyxXQUFXLEdBQUc7O0dBRTNCLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7O0dBRWxEOztFQUVEOztDQUVELFNBQVMsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLFFBQVEsR0FBRzs7RUFFdEQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztFQUM5QyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDOztFQUU5QyxLQUFLLFFBQVEsQ0FBQyxZQUFZLEdBQUc7O0dBRTVCLFFBQVEsQ0FBQyxZQUFZLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUM7O0dBRXBEOztFQUVELEtBQUssUUFBUSxDQUFDLFlBQVksR0FBRzs7R0FFNUIsUUFBUSxDQUFDLFlBQVksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQzs7R0FFcEQ7O0VBRUQsS0FBSyxRQUFRLENBQUMsV0FBVyxHQUFHOztHQUUzQixRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDOztHQUVsRDs7RUFFRCxLQUFLLFFBQVEsQ0FBQyxPQUFPLEdBQUc7O0dBRXZCLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7R0FDMUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQzs7R0FFOUM7O0VBRUQsS0FBSyxRQUFRLENBQUMsU0FBUyxHQUFHOztHQUV6QixRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO0dBQzlDLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7O0dBRXhEOztFQUVELEtBQUssUUFBUSxDQUFDLGVBQWUsR0FBRzs7R0FFL0IsUUFBUSxDQUFDLGVBQWUsQ0FBQyxL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QUFFLENBQUM7O0NBRTVCLElBQUksQ0FBQyxJQUFJLEdBQUcsbUJBQW1CLENBQUM7Ozs7Q0FJaEMsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDOzs7O0NBSWxCLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUNuQixJQUFJLElBQUksR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO0NBQ2pELElBQUksR0FBRyxFQUFFLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Q0FDbEMsSUFBSSxNQUFNLENBQUM7Ozs7Q0FJWCxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsVUFBVSxHQUFHOzs7O0VBSXRDLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7O0VBRTNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUU1QyxJQUFJLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0dBRXRCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUUxQixLQUFLLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQzFCLEtBQUssR0FBRyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQ3RDLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNyQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7O0lBRXJDLEdBQUcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFbEMsS0FBSyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssU0FBUyxHQUFHOztLQUVqQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7S0FFeEQ7O0lBRUQ7O0dBRUQ7Ozs7RUFJRCxNQUFNLEdBQUcsSUFBSSxLQUFLLEdBQUc7O0dBRXBCLENBQUMsR0FBRyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7O0dBRWpCLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztHQUN2QyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUM7O0dBRTlDLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztHQUN2QyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUM7O0dBRTlDOztFQUVELE1BQU0sS0FBSyxRQUFRLElBQUksUUFBUSxDQUFDLGdCQUFnQixHQUFHOztFQUVuRCxJQUFJLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDO0VBQzlCLElBQUksS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7RUFDeEIsSUFBSSxNQUFNLEVBQUUsTUFBTSxDQUFDOztFQUVuQixNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7RUFFdkIsS0FBSyxRQUFRLENBQUMsS0FBSyxLQUFLLElBQUksR0FBRzs7OztHQUk5QixRQUFRLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7R0FDeEMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7R0FDekIsTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7O0dBRXpCLEtBQUssTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEdBQUc7O0lBRTFCLE1BQU0sR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7SUFFbEU7Ozs7R0FJRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRzs7SUFFL0MsS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFcEIsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDcEIsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7O0lBRXBCLE1BQU0sQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEtBQUssS0FBSyxHQUFHLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRzs7S0FFdkQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O01BRTFCLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztNQUM5QixLQUFLLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO01BQzFDLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztN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QUFDLEVBQUUsQ0FBQyxDQUFDOzs7O0NBSVQsSUFBSSxVQUFVLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzs7Q0FFNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0VBRWhDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7O0VBRW5CLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUVoQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDOzs7O0dBSW5CLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQztHQUN0QixRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7Ozs7OztHQU1sQyxLQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHOztJQUVuQixFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQzVCLEVBQUUsQ0FBQyxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztJQUV4QixNQUFNOztJQUVOLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDNUIsRUFBRSxDQUFDLFVBQVUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7O0lBRXhCOztHQUVELEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUc7O0lBRW5CLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDNUIsRUFBRSxDQUFDLFVBQVUsRUFBRSxFQUFFLEVBQUUsRUFBRSxF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QyxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDOztHQUV2QyxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDOztHQUVwQixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFOUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEdBQUc7O0tBRTVCLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7O0tBRWpCLE1BQU07O0tBRU4sQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQzs7S0FFOUM7O0lBRUQ7O0dBRUQ7Ozs7RUFJRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFN0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFN0MsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0lBRTVCLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUc7O0tBRWxCLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7S0FDOUIsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztLQUM5QixVQUFVLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMs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RUFBRSxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztHQUNoRCxHQUFHLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDOztHQUVoRCxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV2RCxJQUFJLEdBQUcsR0FBRyxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUM7O0dBRTlCLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7R0FDaEMsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUNoQyxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDOztHQUVoQzs7RUFFRDs7Q0FFRCxTQUFTLFNBQVMsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEdBQUc7O0VBRWpELEtBQUssRUFBRSxPQUFPLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUc7O0dBRXhDLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7R0FFOUI7O0VBRUQsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUc7O0dBRS9DLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLEdBQUcsQ0FB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LEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDO0dBQ3ZELENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO0dBQ3ZELENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0VBQ3hELENBQUM7O0NBRUYsSUFBSSxPQUFPLEdBQUc7R0FDWixDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUU7R0FDakUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0dBQ2pFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztHQUNqRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7RUFDbEUsQ0FBQzs7Q0FFRix3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDOztDQUV6RSxJQUFJLENBQUMsSUFBSSxHQUFHLDJCQUEyQixDQUFDOztDQUV4QyxJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLE1BQU0sRUFBRSxNQUFNO0VBQ2QsTUFBTSxFQUFFLE1BQU07RUFDZCxDQUFDOztDQUVGOztBQUVELHlCQUF5QixDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLHdCQUF3QixDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQzFGLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcseUJBQXlCLENBQUM7Ozs7Ozs7OztBQVM1RSxTQUFTLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUc7O0NBRS9DLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLENBQUM7O0NBRW5DLElBQUksQ0FBQyxVQUFVLEdBQUc7RUFDakIsTUFBTSxFQUFFLE1BQU07RUFDZCxNQUFNLEVBQUUsTUFBTTtFQUNkLENBQUM7O0NBRUYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksMEJBQTBCLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUM7Q0FDNUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDOztDQUVyQjs7QUFFRCxvQkFBb0IsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDckUsb0JBQW9CLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQzs7OztBQUlsRSxTQUFTLDBCQUEwQixFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUc7O0NBRXJELElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0NBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7O0NBRWQsSUFBSSxRQUFRLEdBQUc7OztFQUdkLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUM7RUFDOUIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQzFCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUMzQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQzs7O0dBRzFCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztHQUMzQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQzs7O0VBRzFCLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztHQUMzQixDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQzs7O0VBRzFCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUM1QixFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztFQUMxQixDQUFDOztDQUVGLElBQUksT0FBTyxHQUFHO0dBQ1osQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFO0dBQ3pDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRTtFQUMxQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUM7R0FDekMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO0dBQ3pDLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRTtHQUN6QyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUU7R0FDekMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO0VBQzFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQztHQUN6QyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLEdB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RSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0dBRTdCLEVBQUUsR0FBRyxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0dBQzdCLEVBQUUsR0FBRyxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDOztHQUU3QixFQUFFLEdBQUcsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztHQUM3QixFQUFFLEdBQUcsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQzs7R0FFN0IsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLE9BQU8sS0FBSyxDQUFDOztHQUUvRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0dBQzNCLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUM7R0FDakMsSUFBSSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQzs7R0FFakMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztHQUM1QixFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0dBQzVCLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7O0dBRTVCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMs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QUMsR0FBRzs7S0FFOUIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLENBQUMsUUFBUSxTQUFTLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRzs7S0FFMUUsTUFBTTs7S0FFTixTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQyxRQUFRLFNBQVMsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHOztLQUUxRTs7SUFFRDs7R0FFRDs7RUFFRCxTQUFTLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxxQkFBcUIsR0FBRzs7R0FFbkcsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7R0FDN0UsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7O0dBRTdFLElBQUksVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztHQUMzQyxJQUFJLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7O0dBRTNDLElBQUksS0FBSyxJQUFJLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQztHQUMvQyxJQUFJLFFBQVEsR0FBRyxNQUFNLEdBQUcsVUFBVSxHQUFHLE1BQU0sR0FBRyxVQUFVLENBQUM7O0dBRXpELEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUMsT0FBTyxHQUFHOzs7O0lBSXpDLElBQUksUUFBUSxDQUFDO0lBQ2IsS0FBSyxLQUFLLEdBQUcsQ0FB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RCxJQUFJLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUM3QyxJQUFJLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUM3QyxLQUFLLE1BQU0sS0FBSyxDQUFDLEdBQUc7OztLQUduQixLQUFLLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRzs7TUFFaEMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO01BQzlDLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQzs7TUFFOUMsTUFBTTs7TUFFTixPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7TUFDOUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDOztNQUU5QztLQUNELEtBQUssU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHOztNQUVoQyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7TUFDOUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDOztNQUU5QyxNQUFNOztNQUVOLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztNQUM5QyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7O01BRTlDOztLQUVELE1BQU07OztLQUdOLEtBQUssU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHOztNQUVoQyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7TUFDOUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDOztNQUU5QyxNQUFNOztNQUVOLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztNQUM5QyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7O01BRTlDO0tBQ0QsS0FBSyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUc7O01BRWhDLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztNQUM5QyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7O01BRTlDLE1BQU07O01BRU4sT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO01BQzlDLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQzs7TUFFOUM7O0tBRUQ7SUFDRCxLQUFLLFVBQVUsSUFBSSxVQUFVLEdBQUc7O0tBRS9CLEtBQUssVUFBVSxJQUFJLFVBQVUsR0FBRyxPQUFPLEVBQUUsQ0FBQztLQUMxQyxLQUFLLFVBQVUsS0FBSyxVQUFVLEdBQUc7O01BRWhDLEtBQUsscUJBQXFCLElBQUksT0FBTyxFQUFFLENBQUM7TUFDeEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDOztNQUVuQjtLQUNELEtBQUssVUFBVSxJQUFJLFVBQVUsR0FBRyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDO0tBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUM7O0tBRTVCLE1BQU07O0tBRU4sS0FBSyxVQUFVLElBQUksVUFBVSxHQUFHLE9BQU8sRUFBRSxDQUFDO0tBQzFDLEtBQUssVUFBVSxLQUFLLFVBQVUsR0FBRzs7TUFFaEMsS0FBSyxxQkFBcUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztNQUN4QyxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUM7O01BRW5CO0tBQ0QsS0FBSyxVQUFVLElBQUksVUFBVSxHQUFHLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUM7S0FDNUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQzs7S0FFNUI7O0lBRUQ7O0dBRUQ7O0VBRUQsU0FBUyxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEdBQUc7Ozs7O0dBSzFFLElBQUksVUFBVSxHQUFHLFdBQVcsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0dBQ3RGLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLElBQUksU0FBUyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0dBQy9FLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLElBQUksU0FBUyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDOzs7R0FHL0UsSUFBSSxZQUFZLEdBQUcsVUFBVSxHQUFHLFFBQVEsR0FBRyxVQUFVLEdBQUcsUUFBUSxDQUFDO0dBQ2pFLElBQUksZUFBZSxHQUFHLFVBQVUsR0FBRyxRQUFRLEdBQUcsVUFBVSxHQUFHLFFBQVEsQ0FBQzs7R0FFcEUsS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEdBQUc7Ozs7SUFJaEQsSUFBSSxhQUFhLElBQUksUUFBUSxHQUFHLFFBQVEsR0FBRyxRQUFRLEdBQUcsUUFBUSxDQUFDOzs7SUFHL0QsS0FBSyxZQUFZLEdBQUcsQ0FBQyxHQUFHOzs7S0FHdkIsU0FBUyxFQUFFLGVBQWUsSUFBSSxDQUFDLFFBQVEsYUFBYSxJQUFJLENBQUMsRUFBRSxHQUFHOztLQUU5RCxNQUFNOzs7S0FHTixTQUFTLEVBQUUsZUFBZSxJQUFJLENBQUMsUUFBUSxhQUFhLElBQUksQ0FBQyxFQUFFLEdBQUc7O0tBRTlEOztJQUVELE1BQU07Ozs7SUFJTixTQUFTLGVBQWUsR0FBRyxDQUFDLEdBQUc7O0lBRS9COztHQUVEOzs7RUFHRCxTQUFTLFdBQVcsRUFBRSxPQUFPLEVBQUUsS0FBSyxHQUFHOztHQUV0QyxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7R0FDN0IsSUFBSSxJQUFJLENBQUM7O0dBRVQsU0FBUyxxQkFBcUIsRUFBRSxVQUFVLEVBQUUsU0FBUyxHQUFHOzs7SUFHdkQsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7O0lBRXBDLElBQUksWUFBWSxHQUFHLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDbEMsS0FBSyxZQUFZLEdBQUcsQ0FBQyxLQUFLLFlBQVksR0FBRyxZQUFZLENBQUM7O0lBRXRELElBQUksWUFBWSxHQUFHLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDbEMsS0FBSyxZQUFZLEdBQUcsWUFBWSxHQUFHLFlBQVksR0FBRyxDQUFDLENBQUM7O0lBRXBELElBQUksV0FBVyxHQUFHLGtCQUFrQixFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDO0lBQzdILEtBQUssRUFBRSxXQUFXLEdBQUc7OztLQUdwQixPQUFPLEtBQUssQ0FBQzs7S0FFYjs7O0lBR0QsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7O0lBRWxDLElBQUksV0FBVyxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDaEMsS0FBSyxXQUFXLEdBQUcsQ0FBQyxLQUFLLFdBQVcsR0FBRyxXQUFXLENBQUM7O0lBRW5ELElBQUksV0FBVyxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDaEMsS0FBSyxXQUFXLEdBQUcsV0FBVyxHQUFHLFdBQVcsR0FBRyxDQUFDLENBQUM7O0lBRWpELFdBQVcsR0FBRyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQztJQUNySCxLQUFLLEVBQUUsV0FBVyxHQUFHOzs7S0FHcEIsT0FBTyxLQUFLLENBQUM7O0tBRWI7O0lBRUQsT0FBTyxJQUFJLENBQUM7O0lBRVo7O0dBRUQsU0FBUyxtQkFBbUIsRUFBRSxTQUFTLEVBQUUsUUFBUSxHQUFHOzs7SUFHbkQsSUFBSSxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQztJQUNoQyxNQUFNLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsSUFBSSxHQUFHLEdBQUc7O0tBRTlDLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUM7S0FDNUMsWUFBWSxHQUFHLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztLQUNuRyxLQUFLLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDOztLQUU1Qzs7SUFFRCxPQUFPLEtBQUssQ0FBQzs7SUFFYjs7R0FFRCxJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7O0dBRXBCLFNBQVMsa0JBQWtCLEVBQUUsU0FBUyxFQUFFLFFBQVEsR0FBRzs7O0lBR2xELElBQUksS0FBSyxFQUFFLE9BQU87S0FDakIsSUFBSSxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUM7SUFDN0IsTUFBTSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLEtBQUssR0FBRyxHQUFHOztLQUV0RCxPQUFPLEdBQUcsS0FBSyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0tBQ3RDLE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEdBQUcsR0FBRzs7TUFFaEQsT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQztNQUM5QyxZQUFZLEdBQUcscUJBQXFCLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDO01BQ3ZHLEtBQUssWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksT0FBTyxJQUFJLENBQUM7O01BRTVDOztLQUVEO0lBQ0QsT0FBTyxLQUFLLENBQUM7O0lBRWI7O0dBRUQsSUFBSSxTQUFTLEVBQUUsVUFBVTtJQUN4QixPQUFPLEVBQUUsTUFBTTtJQUNmLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxHQUFHLEVBQUU7SUFDaEMsU0FBUyxFQUFFLFNBQVM7SUFDcEIsUUFBUSxFQUFFLFFBQVEsQ0FBQzs7R0FFcEIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFbEQsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFckI7O0dBRUQsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0dBQ3RCLElBQUksT0FBTyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0dBQ3BDLFFBQVEsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUc7O0lBRS9CLE9BQU8sR0FBRyxDQUFDO0lBQ1gsS0FBSyxPQUFPLEdBQUcsQ0FBQyxHQUFHOztLQUVsQixPQUFPLENBQUMsR0FBRyxFQUFFLDRCQUE0QixHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsZ0NBQWdDLEVBQUUsQ0FBQztLQUNuRyxNQUFNOztLQUVOOzs7O0lBSUQsTUFBTSxVQUFVLEdBQUcsYUFBYSxFQUFFLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLFVBQVUsR0FBRyxHQUFHOztLQUU1RSxPQUFPLEdBQUcsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDO0tBQzlCLFNBQVMsR0FBRyxFQUFFLENBQUMsQ0FBQzs7O0tBR2hCLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHOztNQUU5QyxPQUFPLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDOzs7TUFHMUIsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLE9BQU8sQ0FBQztNQUNyRCxLQUFLLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxTQUFTLEtBQUssU0FBUzs7TUFFckQsSUFBSSxHQUFHLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztNQUN4QixNQUFNLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLEdBQUcsR0FBRzs7T0FFM0MsTUFBTSxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztPQUNwQixLQUFLLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxJQUFJLFNBQVM7T0FDM0QsS0FBSyxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksU0FBUztPQUN4RCxLQUFLLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxTQUFTOztPQUV2RCxTQUFTLEdBQUcsRUFBRSxDQUFDO09BQ2YsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7O09BRTFCLFNBQVMsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUM7T0FDN0MsU0FBUyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7T0FDdEMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUM7T0FDbkMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7T0FFMUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQzs7T0FFNUUsYUFBYSxHQUFHLFVBQVUsQ0FBQzs7Ozs7T0FLM0IsTUFBTTs7T0FFTjtNQUNELEtBQUssU0FBUyxJQUFJLENBQUMsR0FBRyxNQUFNOztNQUU1QixVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDOztNQUU1QjtLQUNELEtBQUssU0FBUyxJQUFJLENBQUMsR0FBRyxNQUFNOztLQUU1Qjs7SUFFRDs7R0FFRCxPQUFPLEtBQUssQ0FBQzs7R0FFYjs7O0VBR0QsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJO0dBQ2pCLEdBQUcsRUFBRSxLQUFLO0dBQ1YsWUFBWSxHQUFHLEVBQUUsQ0FBQzs7OztFQUluQixJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7O0VBRWpDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRWxELEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0dBRXBEOzs7Ozs7RUFNRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFbEQsR0FBRyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0dBRWhELEtBQUssWUFBWSxFQUFFLEdBQUcsRUFBRSxLQUFLLFNBQVMsR0FBRzs7SUFFeEMsT0FBTyxDQUFDLElBQUksRUFBRSxtQ0FBbUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0lBRTVEOztHQUVELFlBQVksRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7O0dBRXhCOzs7RUFHRCxJQUFJLGlCQUFpQixHQUFHLFdBQVcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7O0VBRXRELElBQUksU0FBUyxHQUFHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLENBQUM7Ozs7O0VBS25FLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUVsRCxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV0QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFMUIsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0lBRXRDLEtBQUssR0FBRyxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUM7O0lBRTVCLEtBQUssS0FBSyxLQUFLLFNBQVMsR0FBRzs7S0FFMUIsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQzs7S0FFbEI7O0lBRUQ7O0dBRUQ7O0VBRUQsT0FBTyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7O0VBRTFCOztDQUVELFdBQVcsRUFBRSxXQUFXLEdBQUcsR0FBRzs7RUFFN0IsT0FBTyxVQUFVLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQzs7RUFFbEM7O0NBRUQsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRCRixTQUFTLGVBQWUsRUFBRSxNQUFNLEVBQUUsT0FBTyxHQUFHOztDQUUzQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDOztDQUV0QixJQUFJLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDOztDQUU5QixJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLE1BQU0sRUFBRSxNQUFNO0VBQ2QsT0FBTyxFQUFFLE9BQU87RUFDaEIsQ0FBQzs7Q0FFRixJQUFJLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxxQkFBcUIsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztDQUN4RSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7O0NBRXJCOztBQUVELGVBQWUsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDaEUsZUFBZSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDOzs7O0FBSXhELFNBQVMscUJBQXFCLEVBQUUsTUFBTSxFQUFFLE9BQU8sR0FBRzs7Q0FFakQsS0FBSyxTQUFTLE1BQU0sRUFBRSxLQUFLLFdBQVcsR0FBRzs7RUFFeEMsTUFBTSxHQUFHLEVBQUUsQ0FBQztFQUNaLE9BQU87O0VBRVA7O0NBRUQsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7Q0FFNUIsSUFBSSxDQUFDLElBQUksR0FBRyx1QkFBdUIsQ0FBQzs7Q0FFcEMsTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUM7O0NBRXZELElBQUksQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDOztDQUVyQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQzs7Ozs7Ozs7OztDQVU1Qjs7QUFFRCxxQkFBcUIsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDNUUscUJBQXFCLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxxQkFBcUIsQ0FBQzs7QUFFcEUscUJBQXFCLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxZQUFZOztDQUV2RCxJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLENBQUM7Q0FDeEQsSUFBSSxhQUFhLEdBQUcsaUJBQWlCLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzs7Q0FFbkcsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztDQUM1QyxJQUFJLE9BQU8sR0FBRyxXQUFXLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7O0NBRWpGLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Q0FDaEMsSUFBSSxZQUFZLEdBQUcsY0FBYyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDOztDQUU1RixPQUFPO0VBQ04sUUFBUSxFQUFFLGFBQWE7RUFDdkIsRUFBRSxFQUFFLE9BQU87RUFDWCxLQUFLLEVBQUUsWUFBWTtFQUNuQixDQUFDOztDQUVGLENBQUM7O0FBRUYscUJBQXFCLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxXQUFXLE1BQU0sRUFBRSxPQUFPLEdBQUc7O0NBRTNFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7Q0FDdkIsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7O0NBRWxDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0VBRS9CLElBQUksS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUN4QixJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQzs7RUFFaEM7O0NBRUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0NBQ3RDLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksc0JBQXNCLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUMxRixJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksRUFBRSxJQUFJLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0NBRTlFLENBQUM7O0FBRUYscUJBQXFCLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxXQUFXLEtBQUssRUFBRSxPQUFPLEdBQUc7O0NBRXRFLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Q0FDaEUsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztDQUNwQyxJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO0NBQ2hDLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUM7O0NBRXhCLElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQzs7O0NBR3JCLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDOztDQUVqRSxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztDQUN2RixJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxHQUFHLGNBQWMsR0FBRyxDQUFDLENBQUM7Q0FDekYsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsS0FBSyxTQUFTLEdBQUcsT0FBTyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7O0NBRXBGLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLEtBQUssU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDOztDQUVwRixJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQzs7Q0FFckYsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7O0NBRTVELElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7Q0FDdEMsSUFBSSxVQUFVLEVBQUUsYUFBYSxHQUFHLEtBQUssQ0FBQzs7O0NBR3RDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxXQUFXLEtBQUssU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLGdCQUFnQixDQUFDOztDQUV2RyxJQUFJLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQztDQUM1QyxLQUFLLFdBQVcsR0FBRzs7RUFFbEIsVUFBVSxHQUFHLFdBQVcsQ0FBQyxlQUFlLEVBQUUsS0FBSyxFQUFFLENBQUM7O0VBRWxELGFBQWEsR0FBRyxJQUFJLENBQUM7RUFDckIsWUFBWSxHQUFHLEtBQUssQ0FBQzs7Ozs7O0VBTXJCLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7Ozs7RUFJN0csUUFBUSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7RUFDekIsTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7RUFDdkIsU0FBUyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7O0VBRTFCOzs7O0NBSUQsS0FBSyxFQUFFLFlBQVksR0FBRzs7RUFFckIsYUFBYSxHQUFHLENBQUMsQ0FBQztFQUNsQixjQUFjLEdBQUcsQ0FBQyxDQUFDO0VBQ25CLFNBQVMsR0FBRyxDQUFDLENBQUM7O0VBRWQ7Ozs7Q0FJRCxJQUFJLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQ2pCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQzs7Q0FFakIsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsQ0FBQzs7Q0FFdkQsSUFBSSxRQUFRLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQztDQUNqQyxJQUFJLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDOztDQUU5QixJQUFJLE9BQU8sR0FBRyxFQUFFLFVBQVUsQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLENBQUM7O0NBRW5ELEtBQUssT0FBTyxHQUFHOztFQUVkLFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Ozs7RUFJOUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRTlDLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0dBRW5CLEtBQUssVUFBVSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsR0FBRzs7SUFFdEMsS0FBSyxFQUFFLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQzs7SUFFN0I7O0dBRUQ7O0VBRUQsT0FBTyxHQUFHLEtBQUssQ0FBQzs7RUFFaEI7OztDQUdELElBQUksS0FBSyxHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7Ozs7Q0FJM0QsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDOztDQUV2QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7RUFFOUMsS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFbkIsUUFBUSxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7O0VBRXBDOzs7Q0FHRCxTQUFTLFFBQVEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksR0FBRzs7RUFFbEMsS0FBSyxFQUFFLEdBQUcsR0FBRyxPQUFPLENBQUMsS0FBSyxFQUFFLDJDQUEyQyxFQUFFLENBQUM7O0VBRTFFLE9BQU8sR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLGNBQWMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUM7O0VBRXBEOztDQUVELElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNkLElBQUksRUFBRSxJQUFJLEdBQUcsUUFBUSxDQUFDLE1BQU07RUFDNUIsSUFBSSxFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDOzs7Ozs7Q0FNM0IsU0FBUyxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUc7Ozs7Ozs7OztFQVM1QyxJQUFJLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxHQUFHLENBQUMsQ0FBQzs7Ozs7RUFLeEMsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztHQUMvQixRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDO0VBQzlCLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7R0FDL0IsUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzs7RUFFOUIsSUFBSSxZQUFZLEtBQUssUUFBUSxHQUFHLFFBQVEsR0FBRyxRQUFRLEdBQUcsUUFBUSxFQUFFLENBQUM7OztFQUdqRSxJQUFJLFVBQVUsS0FBSyxRQUFRLEdBQUcsUUFBUSxHQUFHLFFBQVEsR0FBRyxRQUFRLEVBQUUsQ0FBQzs7RUFFL0QsS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEdBQUc7Ozs7OztHQU05QyxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDO0dBQzNDLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxHQUFHLFFBQVEsR0FBRyxRQUFRLEdBQUcsUUFBUSxFQUFFLENBQUM7Ozs7R0FJeEUsSUFBSSxhQUFhLEtBQUssTUFBTSxDQUFDLENBQUMsR0FBRyxRQUFRLEdBQUcsVUFBVSxFQUFFLENBQUM7R0FDekQsSUFBSSxhQUFhLEtBQUssTUFBTSxDQUFDLENBQUMsR0FBRyxRQUFRLEdBQUcsVUFBVSxFQUFFLENBQUM7O0dBRXpELElBQUksYUFBYSxLQUFLLE1BQU0sQ0FBQyxDQUFDLEdBQUcsUUFBUSxHQUFHLFVBQVUsRUFBRSxDQUFDO0dBQ3pELElBQUksYUFBYSxLQUFLLE1BQU0sQ0FBQyxDQUFDLEdBQUcsUUFBUSxHQUFHLFVBQVUsRUFBRSxDQUFDOzs7O0dBSXpELElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRSxhQUFhLEdBQUcsYUFBYSxLQUFLLFFBQVE7S0FDckQsRUFBRSxhQUFhLEdBQUcsYUFBYSxLQUFLLFFBQVE7TUFDM0MsUUFBUSxHQUFHLFFBQVEsR0FBRyxRQUFRLEdBQUcsUUFBUSxFQUFFLENBQUM7Ozs7R0FJL0MsU0FBUyxLQUFLLGFBQWEsR0FBRyxRQUFRLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztHQUN2RCxTQUFTLEtBQUssYUFBYSxHQUFHLFFBQVEsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDOzs7O0dBSXZELElBQUksYUFBYSxLQUFLLFNBQVMsR0FBRyxTQUFTLEdBQUcsU0FBUyxHQUFHLFNBQVMsRUFBRSxDQUFDO0dBQ3RFLEtBQUssYUFBYSxJQUFJLENBQUMsR0FBRzs7SUFFekIsT0FBTyxJQUFJLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUM7O0lBRTNDLE1BQU07O0lBRU4sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDOztJQUUzQzs7R0FFRCxNQUFNOzs7O0dBSU4sSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0dBQ3pCLEtBQUssUUFBUSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEdBQUc7O0lBRWhDLEtBQUssUUFBUSxHQUFHLE1BQU0sQ0FBQyxPQUFPLEdBQUc7O0tBRWhDLFlBQVksR0FBRyxJQUFJLENBQUM7O0tBRXBCOztJQUVELE1BQU07O0lBRU4sS0FBSyxRQUFRLEdBQUcsRUFBRSxNQUFNLENBQUMsT0FBTyxHQUFHOztLQUVsQyxLQUFLLFFBQVEsR0FBRyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEdBQUc7O01BRWxDLFlBQVksR0FBRyxJQUFJLENBQUM7O01BRXBCOztLQUVELE1BQU07O0tBRU4sS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEdBQUc7O01BRXRELFlBQVksR0FBRyxJQUFJLENBQUM7O01BRXBCOztLQUVEOztJQUVEOztHQUVELEtBQUssWUFBWSxHQUFHOzs7SUFHbkIsU0FBUyxHQUFHLEVBQUUsUUFBUSxDQUFDO0lBQ3ZCLFNBQVMsR0FBRyxRQUFRLENBQUM7SUFDckIsU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUM7O0lBRXRDLE1BQU07OztJQUdOLFNBQVMsR0FBRyxRQUFRLENBQUM7SUFDckIsU0FBUyxHQUFHLFFBQVEsQ0FBQztJQUNyQixTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0lBRTFDOztHQUVEOztFQUVELE9BQU8sSUFBSSxPQUFPLEVBQUUsU0FBUyxHQUFHLFNBQVMsRUFBRSxTQUFTLEdBQUcsU0FBUyxFQUFFLENBQUM7O0VBRW5FOzs7Q0FHRCxJQUFJLGdCQUFnQixHQUFHLEVBQUUsQ0FBQzs7Q0FFMUIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRzs7RUFFdkYsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7RUFDdEIsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7O0VBS3RCLGdCQUFnQixFQUFFLENBQUMsRUFBRSxHQUFHLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztFQUVoRjs7Q0FFRCxJQUFJLGNBQWMsR0FBRyxFQUFFO0VBQ3RCLGdCQUFnQixFQUFFLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDOztDQUVqRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7RUFFOUMsS0FBSyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFbkIsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDOztFQUV0QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFakYsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDdEIsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7OztHQUd0QixnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsR0FBRyxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7R0FFMUU7O0VBRUQsY0FBYyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO0VBQ3hDLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDOztFQUVqRTs7Ozs7Q0FLRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsRUFBRSxDQUFDLEdBQUcsR0FBRzs7OztFQUl0QyxDQUFDLEdBQUcsQ0FBQyxHQUFHLGFBQWEsQ0FBQztFQUN0QixDQUFDLEdBQUcsY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDakQsRUFBRSxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDOzs7O0VBSTdDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUVoRCxJQUFJLEdBQUcsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7R0FFM0QsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV6Qjs7OztFQUlELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUU5QyxLQUFLLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ25CLGdCQUFnQixHQUFHLGNBQWMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0lBRTlDLElBQUksR0FBRyxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLGdCQUFnQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztJQUV6RCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0lBRXpCOztHQUVEOztFQUVEOztDQUVELEVBQUUsR0FBRyxTQUFTLENBQUM7Ozs7Q0FJZixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsR0FBRzs7RUFFN0IsSUFBSSxHQUFHLFlBQVksR0FBRyxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFNUYsS0FBSyxFQUFFLGFBQWEsR0FBRzs7R0FFdEIsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFdkIsTUFBTTs7OztHQUlOLE1BQU0sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7R0FDaEUsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7R0FFcEUsU0FBUyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDOztHQUVoRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7R0FFM0M7O0VBRUQ7Ozs7O0NBS0QsSUFBSSxDQUFDLENBQUM7O0NBRU4sTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0VBRS9CLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUU3QixJQUFJLEdBQUcsWUFBWSxHQUFHLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUU1RixLQUFLLEVBQUUsYUFBYSxHQUFHOztJQUV0QixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0lBRXhDLE1BQU07Ozs7SUFJTixNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ2hFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7O0lBRXBFLFNBQVMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQzs7SUFFaEUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUM7O0lBRTNDOztHQUVEOztFQUVEOzs7Ozs7Q0FNRCxNQUFNLENBQUMsR0FBRyxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0VBRTNDLENBQUMsR0FBRyxDQUFDLEdBQUcsYUFBYSxDQUFDO0VBQ3RCLENBQUMsR0FBRyxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNqRCxFQUFFLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7Ozs7RUFJN0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRWhELElBQUksR0FBRyxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLGdCQUFnQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0dBQzNELENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDOztHQUVoQzs7OztFQUlELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUU5QyxLQUFLLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ25CLGdCQUFnQixHQUFHLGNBQWMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0lBRTlDLElBQUksR0FBRyxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLGdCQUFnQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztJQUV6RCxLQUFLLEVBQUUsYUFBYSxHQUFHOztLQUV0QixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzs7S0FFaEMsTUFBTTs7S0FFTixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOztLQUUvRTs7SUFFRDs7R0FFRDs7RUFFRDs7Ozs7O0NBTUQsYUFBYSxFQUFFLENBQUM7Ozs7Q0FJaEIsY0FBYyxFQUFFLENBQUM7Ozs7O0NBS2pCLFNBQVMsYUFBYSxHQUFHOztFQUV4QixJQUFJLEtBQUssR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7RUFFbkMsS0FBSyxZQUFZLEdBQUc7O0dBRW5CLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztHQUNkLElBQUksTUFBTSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUM7Ozs7R0FJMUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0lBRTdCLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDbEIsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUM7O0lBRWpFOztHQUVELEtBQUssR0FBRyxLQUFLLEdBQUcsYUFBYSxHQUFHLENBQUMsQ0FBQztHQUNsQyxNQUFNLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQzs7OztHQUl0QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFN0IsSUFBSSxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNsQixFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQzs7SUFFakU7O0dBRUQsTUFBTTs7OztHQUlOLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUU3QixJQUFJLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ2xCLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztJQUV0Qzs7OztHQUlELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUU3QixJQUFJLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ2xCLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLEtBQUssRUFBRSxDQUFDOztJQUVuRjs7R0FFRDs7RUFFRCxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsS0FBSyxTQUFTLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQzs7RUFFN0c7Ozs7Q0FJRCxTQUFTLGNBQWMsR0FBRzs7RUFFekIsSUFBSSxLQUFLLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7RUFDbkMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0VBQ3BCLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLENBQUM7RUFDbEMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUM7O0VBRTlCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUU5QyxLQUFLLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ25CLFNBQVMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUM7OztHQUdoQyxXQUFXLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQzs7R0FFNUI7OztFQUdELEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsR0FBRyxPQUFPLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxDQUFDOzs7RUFHM0g7O0NBRUQsU0FBUyxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVcsR0FBRzs7RUFFMUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQ1QsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7O0VBRW5CLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHOztHQUVuQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ04sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7R0FDVixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDOzs7O0dBSXBDLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDUixFQUFFLEdBQUcsS0FBSyxHQUFHLGFBQWEsR0FBRyxDQUFDLENBQUM7O0dBRWhDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUUzQixJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0lBRTdCLElBQUksQ0FBQyxHQUFHLFdBQVcsR0FBRyxDQUFDLEdBQUcsS0FBSztLQUM5QixDQUFDLEdBQUcsV0FBVyxHQUFHLENBQUMsR0FBRyxLQUFLO0tBQzNCLENBQUMsR0FBRyxXQUFXLEdBQUcsQ0FBQyxHQUFHLEtBQUs7S0FDM0IsQ0FBQyxHQUFHLFdBQVcsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDOztJQUU3QixFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFdkM7O0dBRUQ7O0VBRUQ7O0NBRUQsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUc7O0VBRXJCLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDdEIsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUN0QixXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUV0Qjs7O0NBR0QsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUc7O0VBRXRCLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNmLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNmLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7RUFFZixJQUFJLFNBQVMsR0FBRyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztFQUN6QyxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsU0FBUyxHQUFHLENBQUMsRUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7RUFFbkcsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ2xCLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUNsQixLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0VBRWxCOztDQUVELFNBQVMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsYUFBYSxHQUFHOztFQUU1RixTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDZixTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDZixTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRWYsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2YsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2YsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDOzs7RUFHZixJQUFJLFNBQVMsR0FBRyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztFQUN6QyxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLENBQUMsRUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0VBRXZILEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUNsQixLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7RUFDbEIsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztFQUVsQixLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7RUFDbEIsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ2xCLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7RUFFbEI7O0NBRUQsU0FBUyxTQUFTLEVBQUUsS0FBSyxHQUFHOztFQUUzQixZQUFZLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDOUMsYUFBYSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ25ELGFBQWEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUNuRCxhQUFhLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7O0VBRW5EOzs7Q0FHRCxTQUFTLEtBQUssRUFBRSxPQUFPLEdBQUc7O0VBRXpCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDO0VBQzFCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDOztFQUUxQjs7Q0FFRCxLQUFLLEVBQUUsT0FBTyxDQUFDLE1BQU0sR0FBRzs7RUFFdkIsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsQ0FBQztFQUM5QixJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxJQUFJLHNCQUFzQixFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ2hGLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLElBQUksc0JBQXNCLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7RUFFOUU7O0NBRUQsQ0FBQzs7QUFFRixlQUFlLENBQUMsZ0JBQWdCLEdBQUc7O0NBRWxDLGFBQWEsRUFBRSxXQUFXLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUc7O0VBRXRFLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDakMsSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDckMsSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNqQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNyQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ2pDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOztFQUVyQyxPQUFPO0dBQ04sSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtHQUN2QixJQUFJLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0dBQ3ZCLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7R0FDdkIsQ0FBQzs7RUFFRjs7Q0FFRCxrQkFBa0IsRUFBRSxXQUFXLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxHQUFHOztFQUVuRixJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ2pDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ3JDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ3JDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDakMsSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDckMsSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDckMsSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNqQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNyQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztFQUNyQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ2pDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0VBQ3JDLElBQUksR0FBRyxHQUFHLFFBQVEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOztFQUVyQyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRzs7R0FFbkMsT0FBTztJQUNOLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFO0lBQzNCLElBQUksT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFO0lBQzNCLENBQUM7O0dBRUYsTUFBTTs7R0FFTixPQUFPO0lBQ04sSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUU7SUFDM0IsSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUU7SUFDM0IsSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUU7SUFDM0IsSUFBSSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUU7SUFDM0IsQ0FBQzs7R0FFRjs7RUFFRDtDQUNELENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdUJGLFNBQVMsWUFBWSxHQUFHLElBQUksRUFBRSxVQUFVLEdBQUc7O0NBRTFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDOztDQUUzQixJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLElBQUksRUFBRSxJQUFJO0VBQ1YsVUFBVSxFQUFFLFVBQVU7RUFDdEIsQ0FBQzs7Q0FFRixJQUFJLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQztDQUN0RSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7O0NBRXJCOztBQUVELFlBQVksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDN0QsWUFBWSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDOzs7O0FBSWxELFNBQVMsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLFVBQVUsR0FBRzs7Q0FFL0MsVUFBVSxHQUFHLFVBQVUsSUFBSSxFQUFFLENBQUM7O0NBRTlCLElBQUksSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7O0NBRTNCLEtBQUssRUFBRSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sT0FBTyxLQUFLLEdBQUc7O0VBRXhDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsc0VBQXNFLEVBQUUsQ0FBQztFQUN4RixPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7O0VBRXRCOztDQUVELElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLGFBQWEsRUFBRSxDQUFDOzs7O0NBSXBGLFVBQVUsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sS0FBSyxTQUFTLEdBQUcsVUFBVSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7Ozs7Q0FJN0UsS0FBSyxVQUFVLENBQUMsY0FBYyxLQUFLLFNBQVMsR0FBRyxVQUFVLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztDQUM5RSxLQUFLLFVBQVUsQ0FBQyxTQUFTLEtBQUssU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO0NBQ25FLEtBQUssVUFBVSxDQUFDLFlBQVksS0FBSyxTQUFTLEdBQUcsVUFBVSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7O0NBRTdFLHFCQUFxQixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDOztDQUV2RCxJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDOztDQUVqQzs7QUFFRCxrQkFBa0IsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNoRixrQkFBa0IsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLGtCQUFrQixDQUFDOzs7Ozs7Ozs7O0FBVTlELFNBQVMsY0FBYyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFdBQVcsR0FBRzs7Q0FFOUcsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7Q0FFdEIsSUFBSSxDQUFDLElBQUksR0FBRyxnQkFBZ0IsQ0FBQzs7Q0FFN0IsSUFBSSxDQUFDLFVBQVUsR0FBRztFQUNqQixNQUFNLEVBQUUsTUFBTTtFQUNkLGFBQWEsRUFBRSxhQUFhO0VBQzVCLGNBQWMsRUFBRSxjQUFjO0VBQzlCLFFBQVEsRUFBRSxRQUFRO0VBQ2xCLFNBQVMsRUFBRSxTQUFTO0VBQ3BCLFVBQVUsRUFBRSxVQUFVO0VBQ3RCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLENBQUM7O0NBRUYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksb0JBQW9CLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQztDQUMzSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7O0NBRXJCOztBQUVELGNBQWMsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDL0QsY0FBYyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDOzs7O0FBSXRELFNBQVMsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVyxHQUFHOztDQUVwSCxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDOztDQUU1QixJQUFJLENBQUMsSUFBSSxHQUFHLHNCQUFzQixDQUFDOztDQUVuQyxJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLE1BQU0sRUFBRSxNQUFNO0VBQ2QsYUFBYSxFQUFFLGFBQWE7RUFDNUIsY0FBYyxFQUFFLGNBQWM7RUFDOUIsUUFBUSxFQUFFLFFBQVE7RUFDbEIsU0FBUyxFQUFFLFNBQVM7RUFDcEIsVUFBVSxFQUFFLFVBQVU7RUFDdEIsV0FBVyxFQUFFLFdBQVc7RUFDeEIsQ0FBQzs7Q0FFRixNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQzs7Q0FFdEIsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7Q0FDaEUsY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7O0NBRWxFLFFBQVEsR0FBRyxRQUFRLEtBQUssU0FBUyxHQUFHLFFBQVEsR0FBRyxDQUFDLENBQUM7Q0FDakQsU0FBUyxHQUFHLFNBQVMsS0FBSyxTQUFTLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDOztDQUU5RCxVQUFVLEdBQUcsVUFBVSxLQUFLLFNBQVMsR0FBRyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0NBQ3ZELFdBQVcsR0FBRyxXQUFXLEtBQUssU0FBUyxHQUFHLFdBQVcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDOztDQUVoRSxJQUFJLFFBQVEsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUFDOztDQUV4QyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7O0NBRVgsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0NBQ2QsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDOztDQUVkLElBQUksTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7Q0FDM0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7OztDQUkzQixJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7Q0FDakIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0NBQ2xCLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztDQUNqQixJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7Ozs7Q0FJYixNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLGNBQWMsRUFBRSxFQUFFLEdBQUcsR0FBRzs7RUFFM0MsSUFBSSxXQUFXLEdBQUcsRUFBRSxDQUFDOztFQUVyQixJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsY0FBYyxDQUFDOztFQUU1QixNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLGFBQWEsRUFBRSxFQUFFLEdBQUcsR0FBRzs7R0FFMUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLGFBQWEsQ0FBQzs7OztHQUkzQixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxHQUFHLENBQUMsR0FBRyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsR0FBRyxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUM7R0FDdEcsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxVQUFVLEdBQUcsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDO0dBQzdELE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxHQUFHLENBQUMsR0FBRyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsR0FBRyxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUM7O0dBRXBHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7OztHQUk5QyxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7R0FDdkQsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDOzs7O0dBSTdDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7R0FFckIsV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDOztHQUU3Qjs7RUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDOztFQUV6Qjs7OztDQUlELE1BQU0sRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsY0FBYyxFQUFFLEVBQUUsR0FBRyxHQUFHOztFQUUxQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLGFBQWEsRUFBRSxFQUFFLEdBQUcsR0FBRzs7R0FFekMsSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztHQUM3QixJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7R0FDekIsSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztHQUM3QixJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7R0FFakMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLFVBQVUsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQzFELEtBQUssRUFBRSxLQUFLLGNBQWMsR0FBRyxDQUFDLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUUvRTs7RUFFRDs7OztDQUlELElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUM7Q0FDekIsSUFBSSxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUMzRSxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxJQUFJLHNCQUFzQixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQ3hFLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLElBQUksc0JBQXNCLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0NBRWhFOztBQUVELG9CQUFvQixDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUMzRSxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLG9CQUFvQixDQUFDOzs7Ozs7Ozs7QUFTbEUsU0FBUyxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxXQUFXLEdBQUc7O0NBRXRHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDOztDQUUzQixJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLGFBQWEsRUFBRSxhQUFhO0VBQzVCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLFVBQVUsRUFBRSxVQUFVO0VBQ3RCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLENBQUM7O0NBRUYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksa0JBQWtCLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsRUFBRSxDQUFDO0NBQ25JLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzs7Q0FFckI7O0FBRUQsWUFBWSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUM3RCxZQUFZLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7Ozs7QUFJbEQsU0FBUyxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFdBQVcsR0FBRzs7Q0FFNUcsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7Q0FFNUIsSUFBSSxDQUFDLElBQUksR0FBRyxvQkFBb0IsQ0FBQzs7Q0FFakMsSUFBSSxDQUFDLFVBQVUsR0FBRztFQUNqQixXQUFXLEVBQUUsV0FBVztFQUN4QixXQUFXLEVBQUUsV0FBVztFQUN4QixhQUFhLEVBQUUsYUFBYTtFQUM1QixXQUFXLEVBQUUsV0FBVztFQUN4QixVQUFVLEVBQUUsVUFBVTtFQUN0QixXQUFXLEVBQUUsV0FBVztFQUN4QixDQUFDOztDQUVGLFdBQVcsR0FBRyxXQUFXLElBQUksRUFBRSxDQUFDO0NBQ2hDLFdBQVcsR0FBRyxXQUFXLElBQUksRUFBRSxDQUFDOztDQUVoQyxVQUFVLEdBQUcsVUFBVSxLQUFLLFNBQVMsR0FBRyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0NBQ3ZELFdBQVcsR0FBRyxXQUFXLEtBQUssU0FBUyxHQUFHLFdBQVcsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQzs7Q0FFcEUsYUFBYSxHQUFHLGFBQWEsS0FBSyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0NBQy9FLFdBQVcsR0FBRyxXQUFXLEtBQUssU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQzs7OztDQUl6RSxJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7Q0FDakIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0NBQ2xCLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztDQUNqQixJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7Ozs7Q0FJYixJQUFJLE9BQU8sQ0FBQztDQUNaLElBQUksTUFBTSxHQUFHLFdBQVcsQ0FBQztDQUN6QixJQUFJLFVBQVUsS0FBSyxFQUFFLFdBQVcsR0FBRyxXQUFXLEtBQUssV0FBVyxFQUFFLENBQUM7Q0FDakUsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztDQUMzQixJQUFJLEVBQUUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0NBQ3ZCLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzs7OztDQUlULE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsR0FBRyxHQUFHOztFQUVyQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLGFBQWEsRUFBRSxDQUFDLEdBQUcsR0FBRzs7OztHQUl2QyxPQUFPLEdBQUcsVUFBVSxHQUFHLENBQUMsR0FBRyxhQUFhLEdBQUcsV0FBVyxDQUFDOzs7O0dBSXZELE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7R0FDeEMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQzs7R0FFeEMsUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDOzs7O0dBSTlDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7OztHQUl4QixFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxXQUFXLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztHQUMxQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxXQUFXLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQzs7R0FFMUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7R0FFdkI7Ozs7RUFJRCxNQUFNLElBQUksVUFBVSxDQUFDOztFQUVyQjs7OztDQUlELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUMsR0FBRyxHQUFHOztFQUVwQyxJQUFJLGlCQUFpQixHQUFHLENBQUMsS0FBSyxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUM7O0VBRWxELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUV0QyxPQUFPLEdBQUcsQ0FBQyxHQUFHLGlCQUFpQixDQUFDOztHQUVoQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUM7R0FDaEIsSUFBSSxDQUFDLEdBQUcsT0FBTyxHQUFHLGFBQWEsR0FBRyxDQUFDLENBQUM7R0FDcEMsSUFBSSxDQUFDLEdBQUcsT0FBTyxHQUFHLGFBQWEsR0FBRyxDQUFDLENBQUM7R0FDcEMsSUFBSSxDQUFDLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQzs7OztHQUlwQixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDeEIsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV4Qjs7RUFFRDs7OztDQUlELElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUM7Q0FDekIsSUFBSSxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUMzRSxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxJQUFJLHNCQUFzQixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQ3hFLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLElBQUksc0JBQXNCLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0NBRWhFOztBQUVELGtCQUFrQixDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUN6RSxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLGtCQUFrQixDQUFDOzs7Ozs7Ozs7OztBQVc5RCxTQUFTLGFBQWEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEdBQUc7O0NBRS9ELFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDOztDQUU1QixJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLE1BQU0sRUFBRSxNQUFNO0VBQ2QsUUFBUSxFQUFFLFFBQVE7RUFDbEIsUUFBUSxFQUFFLFFBQVE7RUFDbEIsU0FBUyxFQUFFLFNBQVM7RUFDcEIsQ0FBQzs7Q0FFRixJQUFJLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxtQkFBbUIsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDO0NBQzVGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzs7Q0FFckI7O0FBRUQsYUFBYSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUM5RCxhQUFhLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxhQUFhLENBQUM7Ozs7QUFJcEQsU0FBUyxtQkFBbUIsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEdBQUc7O0NBRXJFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRTVCLElBQUksQ0FBQyxJQUFJLEdBQUcscUJBQXFCLENBQUM7O0NBRWxDLElBQUksQ0FBQyxVQUFVLEdBQUc7RUFDakIsTUFBTSxFQUFFLE1BQU07RUFDZCxRQUFRLEVBQUUsUUFBUTtFQUNsQixRQUFRLEVBQUUsUUFBUTtFQUNsQixTQUFTLEVBQUUsU0FBUztFQUNwQixDQUFDOztDQUVGLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztDQUN4QyxRQUFRLEdBQUcsUUFBUSxJQUFJLENBQUMsQ0FBQztDQUN6QixTQUFTLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDOzs7O0NBSXJDLFNBQVMsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7Ozs7Q0FLckQsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0NBQ2pCLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQztDQUNsQixJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7Ozs7Q0FJYixJQUFJLElBQUksQ0FBQztDQUNULElBQUksZUFBZSxHQUFHLEdBQUcsR0FBRyxRQUFRLENBQUM7Q0FDckMsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztDQUMzQixJQUFJLEVBQUUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0NBQ3ZCLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzs7OztDQUlULE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksUUFBUSxFQUFFLENBQUMsR0FBRyxHQUFHOztFQUVsQyxJQUFJLEdBQUcsR0FBRyxRQUFRLEdBQUcsQ0FBQyxHQUFHLGVBQWUsR0FBRyxTQUFTLENBQUM7O0VBRXJELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7RUFDMUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7RUFFMUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHOzs7O0dBSS9DLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7R0FDL0IsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0dBQ3pCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7O0dBRS9CLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7OztHQUk5QyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7R0FDcEIsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzs7R0FFakMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7O0dBR3ZCOztFQUVEOzs7O0NBSUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0VBRWpDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFOUMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzs7R0FFN0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO0dBQ2IsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7R0FDN0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0dBQ2pDLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7Ozs7R0FJakIsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ3hCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFeEI7O0VBRUQ7Ozs7Q0FJRCxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDO0NBQ3pCLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksc0JBQXNCLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Q0FDM0UsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7OztDQUloRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQzs7Ozs7Q0FLNUIsS0FBSyxTQUFTLEtBQUssSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUc7O0VBRWhDLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztFQUMzQyxJQUFJLEVBQUUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0VBQ3ZCLElBQUksRUFBRSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7RUFDdkIsSUFBSSxDQUFDLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7OztFQUl0QixJQUFJLEdBQUcsUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDOztFQUVwQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHOzs7O0dBSXJELEVBQUUsQ0FBQyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztHQUN4QixFQUFFLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7R0FDeEIsRUFBRSxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOzs7O0dBSXhCLEVBQUUsQ0FBQyxDQUFDLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7R0FDL0IsRUFBRSxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztHQUMvQixFQUFFLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDOzs7O0dBSS9CLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDOzs7O0dBSW5DLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztHQUNqRCxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLE9BQU8sRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7R0FDakQsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOztHQUVqRDs7RUFFRDs7Q0FFRDs7QUFFRCxtQkFBbUIsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDMUUsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxtQkFBbUIsQ0FBQzs7Ozs7Ozs7O0FBU2hFLFNBQVMsYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLEdBQUc7O0NBRS9DLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDOztDQUU1QixLQUFLLE9BQU8sYUFBYSxLQUFLLFFBQVEsR0FBRzs7RUFFeEMsT0FBTyxDQUFDLElBQUksRUFBRSwwREFBMEQsRUFBRSxDQUFDOztFQUUzRSxhQUFhLEdBQUcsYUFBYSxDQUFDLGFBQWEsQ0FBQzs7RUFFNUM7O0NBRUQsSUFBSSxDQUFDLFVBQVUsR0FBRztFQUNqQixNQUFNLEVBQUUsTUFBTTtFQUNkLGFBQWEsRUFBRSxhQUFhO0VBQzVCLENBQUM7O0NBRUYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksbUJBQW1CLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUM7Q0FDNUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDOztDQUVyQjs7QUFFRCxhQUFhLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQzlELGFBQWEsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQzs7OztBQUlwRCxTQUFTLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxhQUFhLEdBQUc7O0NBRXJELGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRTVCLElBQUksQ0FBQyxJQUFJLEdBQUcscUJBQXFCLENBQUM7O0NBRWxDLElBQUksQ0FBQyxVQUFVLEdBQUc7RUFDakIsTUFBTSxFQUFFLE1BQU07RUFDZCxhQUFhLEVBQUUsYUFBYTtFQUM1QixDQUFDOztDQUVGLGFBQWEsR0FBRyxhQUFhLElBQUksRUFBRSxDQUFDOzs7O0NBSXBDLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztDQUNqQixJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7Q0FDbEIsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0NBQ2pCLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQzs7OztDQUliLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztDQUNuQixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7Ozs7Q0FJbkIsS0FBSyxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEtBQUssR0FBRzs7RUFFeEMsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDOztFQUVuQixNQUFNOztFQUVOLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUUxQyxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0dBRXhCLElBQUksQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7R0FFM0MsVUFBVSxJQUFJLFVBQVUsQ0FBQztHQUN6QixVQUFVLEdBQUcsQ0FBQyxDQUFDOztHQUVmOztFQUVEOzs7O0NBSUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQztDQUN6QixJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxJQUFJLHNCQUFzQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQzNFLElBQUksQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLElBQUksc0JBQXNCLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Q0FDeEUsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs7Ozs7Q0FLaEUsU0FBUyxRQUFRLEVBQUUsS0FBSyxHQUFHOztFQUUxQixJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDOztFQUVwQixJQUFJLFdBQVcsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztFQUN0QyxJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxDQUFDOztFQUVsRCxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO0VBQ2pDLElBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7Ozs7RUFJOUIsS0FBSyxVQUFVLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxLQUFLLEtBQUssR0FBRzs7R0FFeEQsYUFBYSxHQUFHLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQzs7OztHQUl4QyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7SUFFakQsU0FBUyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7SUFFNUIsS0FBSyxVQUFVLENBQUMsV0FBVyxFQUFFLFNBQVMsRUFBRSxLQUFLLElBQUksR0FBRzs7S0FFbkQsVUFBVSxFQUFFLENBQUMsRUFBRSxHQUFHLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzs7S0FFdEM7O0lBRUQ7O0dBRUQ7O0VBRUQsSUFBSSxLQUFLLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsQ0FBQzs7OztFQUlyRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFakQsU0FBUyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUM1QixhQUFhLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQzs7R0FFbEQ7Ozs7RUFJRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFcEQsSUFBSSxNQUFNLEdBQUcsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUVoQyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztHQUN2QyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7R0FDeEIsR0FBRyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7R0FFL0I7Ozs7RUFJRCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRzs7R0FFNUMsSUFBSSxJQUFJLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUV0QixJQUFJLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsV0FBVyxDQUFDO0dBQ2hDLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxXQUFXLENBQUM7R0FDaEMsSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQzs7R0FFaEMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0dBQ3hCLFVBQVUsSUFBSSxDQUFDLENBQUM7O0dBRWhCOztFQUVEOztDQUVEOztBQUVELG1CQUFtQixDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUMxRSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLG1CQUFtQixDQUFDOzs7Ozs7O0FBT2hFLFNBQVMsYUFBYSxFQUFFLFFBQVEsRUFBRSxjQUFjLEdBQUc7O0NBRWxELGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRTVCLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDOztDQUU1QixJQUFJLENBQUMsVUFBVSxHQUFHO0VBQ2pCLGNBQWMsRUFBRSxjQUFjO0VBQzlCLENBQUM7O0NBRUYsY0FBYyxHQUFHLEVBQUUsY0FBYyxLQUFLLFNBQVMsS0FBSyxjQUFjLEdBQUcsQ0FBQyxDQUFDOzs7O0NBSXZFLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQzs7OztDQUlsQixJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUcsY0FBYyxFQUFFLENBQUM7Q0FDOUQsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO0NBQzlDLElBQUksR0FBRyxFQUFFLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Ozs7Q0FJbEMsSUFBSSxTQUFTLENBQUM7O0NBRWQsS0FBSyxRQUFRLENBQUMsZ0JBQWdCLEdBQUc7O0VBRWhDLFNBQVMsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO0VBQzNCLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsQ0FBQzs7RUFFekMsTUFBTTs7RUFFTixTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDOztFQUU3Qjs7Q0FFRCxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUM7Q0FDMUIsU0FBUyxDQUFDLGtCQUFrQixFQUFFLENBQUM7O0NBRS9CLElBQUksY0FBYyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUM7Q0FDeEMsSUFBSSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQzs7OztDQUk1QixNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHOztFQUVoRCxJQUFJLElBQUksR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRXRCLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUc7O0dBRTlCLEtBQUssR0FBRyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7R0FDMUIsS0FBSyxHQUFHLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUM7R0FDdEMsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO0dBQ3JDLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQzs7R0FFckMsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDOztHQUVsQyxLQUFLLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxTQUFTLEdBQUc7O0lBRWpDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQzs7SUFFcEYsTUFBTTs7SUFFTixLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQzs7SUFFdkI7O0dBRUQ7O0VBRUQ7Ozs7Q0FJRCxNQUFNLEdBQUcsSUFBSSxLQUFLLEdBQUc7O0VBRXBCLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzs7OztFQUlyQixLQUFLLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLFlBQVksR0FBRzs7R0FFdEcsSUFBSSxNQUFNLEdBQUcsY0FBYyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztHQUN4QyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUM7O0dBRTlDLE1BQU0sR0FBRyxjQUFjLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0dBQ3BDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7R0FFOUM7O0VBRUQ7Ozs7Q0FJRCxJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxJQUFJLHNCQUFzQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztDQUUzRTs7QUFFRCxhQUFhLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3BFLGFBQWEsQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQzs7Ozs7Ozs7O0FBU3BELFNBQVMsZ0JBQWdCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFdBQVcsR0FBRzs7Q0FFaEksUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQzs7Q0FFdEIsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQzs7Q0FFL0IsSUFBSSxDQUFDLFVBQVUsR0FBRztFQUNqQixTQUFTLEVBQUUsU0FBUztFQUNwQixZQUFZLEVBQUUsWUFBWTtFQUMxQixNQUFNLEVBQUUsTUFBTTtFQUNkLGNBQWMsRUFBRSxjQUFjO0VBQzlCLGNBQWMsRUFBRSxjQUFjO0VBQzlCLFNBQVMsRUFBRSxTQUFTO0VBQ3BCLFVBQVUsRUFBRSxVQUFVO0VBQ3RCLFdBQVcsRUFBRSxXQUFXO0VBQ3hCLENBQUM7O0NBRUYsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksc0JBQXNCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQUM7Q0FDN0osSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDOztDQUVyQjs7QUFFRCxnQkFBZ0IsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDakUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQzs7OztBQUkxRCxTQUFTLHNCQUFzQixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxXQUFXLEdBQUc7O0NBRXRJLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0NBRTVCLElBQUksQ0FBQyxJQUFJLEdBQUcsd0JBQXdCLENBQUM7O0NBRXJDLElBQUksQ0FBQyxVQUFVLEdBQUc7RUFDakIsU0FBUyxFQUFFLFNBQVM7RUFDcEIsWUFBWSxFQUFFLFlBQVk7RUFDMUIsTUFBTSxFQUFFLE1BQU07RUFDZCxjQUFjLEVBQUUsY0FBYztFQUM5QixjQUFjLEVBQUUsY0FBYztFQUM5QixTQUFTLEVBQUUsU0FBUztFQUNwQixVQUFVLEVBQUUsVUFBVTtFQUN0QixXQUFXLEVBQUUsV0FBVztFQUN4QixDQUFDOztDQUVGLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQzs7Q0FFakIsU0FBUyxHQUFHLFNBQVMsS0FBSyxTQUFTLEdBQUcsU0FBUyxHQUFHLEVBQUUsQ0FBQztDQUNyRCxZQUFZLEdBQUcsWUFBWSxLQUFLLFNBQVMsR0FBRyxZQUFZLEdBQUcsRUFBRSxDQUFDO0NBQzlELE1BQU0sR0FBRyxNQUFNLEtBQUssU0FBUyxHQUFHLE1BQU0sR0FBRyxHQUFHLENBQUM7O0NBRTdDLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztDQUNuRCxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7O0NBRW5ELFNBQVMsR0FBRyxTQUFTLEtBQUssU0FBUyxHQUFHLFNBQVMsR0FBRyxLQUFLLENBQUM7Q0FDeEQsVUFBVSxHQUFHLFVBQVUsS0FBSyxTQUFTLEdBQUcsVUFBVSxHQUFHLEdBQUcsQ0FBQztDQUN6RCxXQUFXLEdBQUcsV0FBVyxLQUFLLFNBQVMsR0FBRyxXQUFXLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Ozs7Q0FJdEUsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0NBQ2pCLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQztDQUNsQixJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7Q0FDakIsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDOzs7O0NBSWIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0NBQ2QsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO0NBQ3BCLElBQUksVUFBVSxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUM7Q0FDNUIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDOzs7O0NBSW5CLGFBQWEsRUFBRSxDQUFDOztDQUVoQixLQUFLLFNBQVMsS0FBSyxLQUFLLEdBQUc7O0VBRTFCLEtBQUssU0FBUyxHQUFHLENBQUMsR0FBRyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7RUFDekMsS0FBSyxZQUFZLEdBQUcsQ0FBQyxHQUFHLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQzs7RUFFN0M7Ozs7Q0FJRCxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDO0NBQ3pCLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksc0JBQXNCLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Q0FDM0UsSUFBSSxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUN4RSxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksRUFBRSxJQUFJLHNCQUFzQixFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDOztDQUVoRSxTQUFTLGFBQWEsR0FBRzs7RUFFeEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQ1QsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztFQUMzQixJQUFJLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDOztFQUUzQixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7OztFQUduQixJQUFJLEtBQUssR0FBRyxFQUFFLFlBQVksR0FBRyxTQUFTLEtBQUssTUFBTSxDQUFDOzs7O0VBSWxELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksY0FBYyxFQUFFLENBQUMsR0FBRyxHQUFHOztHQUV4QyxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7O0dBRWxCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxjQUFjLENBQUM7Ozs7R0FJM0IsSUFBSSxNQUFNLEdBQUcsQ0FBQyxLQUFLLFlBQVksR0FBRyxTQUFTLEVBQUUsR0FBRyxTQUFTLENBQUM7O0dBRTFELE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksY0FBYyxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUV4QyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsY0FBYyxDQUFDOztJQUUzQixJQUFJLEtBQUssR0FBRyxDQUFDLEdBQUcsV0FBVyxHQUFHLFVBQVUsQ0FBQzs7SUFFekMsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNqQyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDOzs7O0lBSWpDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLFFBQVEsQ0FBQztJQUM3QixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxVQUFVLENBQUM7SUFDckMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsUUFBUSxDQUFDO0lBQzdCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQzs7OztJQUk5QyxNQUFNLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDcEQsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDOzs7O0lBSTdDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7OztJQUlyQixRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssR0FBRyxFQUFFLENBQUM7O0lBRTFCOzs7O0dBSUQsVUFBVSxD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Q0FBQzs7Q0FFSixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsUUFBUSxLQUFLLFNBQVMsS0FBSyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0NBQzFELElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxLQUFLLEtBQUssU0FBUyxLQUFLLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztDQUMzRCxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsUUFBUSxLQUFLLFNBQVMsS0FBSyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0NBQzFELElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxLQUFLLEtBQUssU0FBUyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUM7O0NBRWpELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQzs7Q0FFcEM7O0FBRUQsU0FBUyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBRSxFQUFFOztDQUV0RSxXQUFXLEVBQUUsU0FBUzs7Q0FFdEIsV0FBVyxFQUFFLElBQUk7O0NBRWpCLElBQUksRUFBRSxXQUFXLE1BQU0sR0FBRzs7RUFFekIsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQzs7RUFFMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO0VBQ2hDLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztFQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7RUFDaEMsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDOztFQUUxQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7O0VBRXBDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFL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RUFDeEUsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7RUFDN0UsS0FBSyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7RUFDN0UsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsa0JBQWtCLEtBQUssU0FBUyxHQUFHLFFBQVEsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7RUFDbkcsS0FBSyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDckUsS0FBSyxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7RUFDakYsS0FBSyxJQUFJLENBQUMsY0FBYyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7RUFDdkYsS0FBSyxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7RUFDakYsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7RUFDdEQsS0FBSyxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7RUFDbEUsS0FBSyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDckUsS0FBSyxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7RUFDekQsS0FBSyxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7RUFDbEUsS0FBSyxJQUFJLENBQUMsV0FBVyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7RUFDOUUsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDM0UsS0FBSyxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDM0UsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDeEUsS0FBSyxJQUFJLENBQUMsa0JBQWtCLEtBQUssU0FBUyxHQUFHLFFBQVEsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7RUFDbkcsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssU0FBUyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7RUFDN0YsS0FBSyxJQUFJLENBQUMsaUJBQWlCLEtBQUssU0FBUyxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7RUFDaEcsS0FBSyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7RUFDckUsS0FBSyxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7Ozs7RUFJakYsS0FBSyxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7RUFDekQsS0FBSyxJQUFJLENBQUMsZUFBZSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7Ozs7RUFJMUYsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxHQUFHLFVBQVUsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7O0VBRXBFLEtBQUssSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLEdBQUc7O0dBRWxDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztHQUNoRCxRQUFRLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQzs7R0FFNUI7O0VBRUQsS0FBSyxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsT0FBTyxHQUFHLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7RUFDaEYsS0FBSyxJQUFJLENBQUMsU0FBUyxLQUFLLFNB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QUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHOztPQUUxQixVQUFVLEdBQUcsS0FBSyxFQUFFLE1BQU0sR0FBRyxFQUFFLENBQUM7T0FDaEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7T0FFNUQ7O01BRUQ7O0tBRUQsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7O0tBRTVCOztJQUVEOztHQUVEOztFQUVELFNBQVMsU0FBUyxFQUFFLElBQUksRUFBRSxRQUFRLEdBQUc7O0dBRXBDLElBQUksbUJBQW1CLEdBQUcsRUFBRSxJQUFJLENBQUMsbUJBQW1CLEtBQUssU0FBUyxLQUFLLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxDQUFDLENBQUM7O0dBRXBHLEtBQUssSUFBSSxDQUFDLFdBQVcsR0FBRzs7SUFFdkIsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLG1CQUFtQixHQUFHOztLQUUvRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO0tBQzlCLElBQUksQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNwRSxJQUFJLENBQUMsR0FBRyxFQUFFLG1CQUFtQixHQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDcEUsSUFBSSxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFD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VUFBVSxHQUFHLENBQUMsR0FBRyxVQUFVLElBQUksS0FBSyxDQUFDO0NBQzdDLFFBQVEsVUFBVSxHQUFHLEtBQUssR0FBRyxVQUFVLElBQUksS0FBSyxDQUFDOztDQUVqRCxLQUFLLFVBQVUsR0FBRyxNQUFNLENBQUMsT0FBTyxHQUFHOztFQUVsQyxLQUFLLFVBQVUsR0FBRzs7R0FFakIsVUFBVSxHQUFHLENBQUMsQ0FBQzs7R0FFZixNQUFNOztHQUVOLFVBQVUsR0FBRyxLQUFLLENBQUM7O0dBRW5COztFQUVEOztDQUVELEtBQUssSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLElBQUksRUFBRSxVQUFVLEdBQUc7O0VBRS9DLEtBQUssVUFBVSxLQUFLLEtBQUssR0FBRzs7R0FFM0IsVUFBVSxHQUFHLEVBQUUsS0FBSyxDQUFDOztHQUVyQixNQUFNOztHQUVOLFVBQVUsR0FBRyxVQUFVLEdBQUcsS0FBSyxDQUFDOztHQUVoQzs7RUFFRDs7Q0FFRCxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsR0FBRyxVQUFVLENBQUM7Q0FDOUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUM7Q0FDbkQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUM7O0NBRW5ELEtBQUssSUFBSSxDQUFDLFNBQVMsS0FBSyxDQUFDLEdBQUc7O0VBRTNCLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0VBQ3JDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDOztFQUVyQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztFQUNyQixJ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R0FBRyxJQUFJLGlCQUFpQixFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDO0NBQy9ELFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUM3QixRQUFRLENBQUMsTUFBTSxFQUFFLElBQUksT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQzVDLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUM7O0NBRXJCLElBQUksUUFBUSxHQUFHLElBQUksaUJBQWlCLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUM7Q0FDL0QsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUMzQixRQUFRLENBQUMsTUFBTSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztDQUMxQyxJQUFJLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDOztDQUVyQixJQUFJLFFBQVEsR0FBRyxJQUFJLGlCQUFpQixFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDO0NBQy9ELFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUM3QixRQUFRLENBQUMsTUFBTSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQzVDLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUM7O0NBRXJCLElBQUksUUFBUSxHQUFHLElBQUksaUJBQWlCLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVB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QUFTLElBQUksRUFBRSxDQUFDLENBQUM7O0lBRTNCLEtBQUssU0FBUyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsUUFBUSxHQUFHOztLQUUxQyxTQUFTLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUM7S0FDcEMsU0FBUyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQzs7S0FFcEM7O0lBRUQsS0FBSyxTQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRzs7S0FFekIsU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7S0FDbkIsU0FBUyxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQzs7S0FFckM7O0lBRUQ7O0dBRUQsTUFBTTs7R0FFTixTQUFTLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQzs7R0FFckQsS0FBSyxTQUFTLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUM7O0dBRS9EOztFQUVELElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7RUFDbEgsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQzs7RUFFOUIsS0FBSyxRQUFRLEtBQUssU0FBUyxDQUFDLFlBQVksR0FBRzs7R0FFMUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUM7R0FDdEQsSUFBSSxDQUFDLHFCQUFxQixFQUFFLFNBQVMsQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDOztHQUVsRSxJQUFJLENBQUMscUJBQXFCLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDOztH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SSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztDQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztDQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztDQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQzs7OztDQUlwQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztDQUNoQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztDQUNoQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztDQUNoQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQzs7OztDQUloQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztDQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztDQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQzs7OztDQUkvQixPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsQ0FBQztDQUNqQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQzs7OztDQUloQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztDQUNwQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQzs7Q0FFcEMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7Q0FDcEMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7O0NBRXBDLFNBQVMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxHQUFHOztFQUUvQixRQUFRLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO0VBQ3JCLFFBQVEsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUM7O0VBRXJCOztDQUVELFNBQVMsUUFBUSxFQUFFLEVBQUUsRUFBRSxLQUFLLEdBQUc7O0VBRTlCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUN6QixNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7O0VBRXpDLEtBQUssUUFBUSxFQUFFLEVBQUUsRUFBRSxLQUFLLFNBQVMsR0FBRzs7R0FFbkMsUUFBUSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7R0FFcEI7O0VBRUQsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDOztFQUVuRDs7Q0FFRCxRQUFRLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxJQUFJLHNCQUFzQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0NBQy9FLFFBQVEsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLElBQUksc0JBQXNCLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7O0NBRTFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQzs7Q0FFOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Q0FDckIsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzs7Q0FFL0UsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO0NBQ2pDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7O0NBRTlCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDOztDQUV6QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7O0NBRWQ7O0FBRUQsWUFBWSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNqRSxZQUFZLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7O0FBRWxELFlBQVksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFlBQVk7O0NBRTNDLElBQUksUUFBUSxFQUFFLFFBQVEsQ0FBQzs7Q0FFdkIsSUFBSSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztDQUMzQixJQUFJLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDOztDQUUxQixTQUFTLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUc7O0VBRW5DLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7O0VBRTFDLElBQUksTUFBTSxHQUFHLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQzs7RUFFL0IsS0FBSyxNQUFNLEtBQUssU0FBUyxHQUFHOztHQUUzQixJQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxDQUFDOztHQUVuRCxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHOztJQUVqRCxRQUFRLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDOztJQUU3RDs7R0FFRDs7RUFFRDs7Q0FFRCxPQUFPLFNBQVMsTUFBTSxHQUFHOztFQUV4QixRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztFQUN6QixRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzs7RUFFekIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7O0VBS2pCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDOzs7O0VBSTdELFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzNCLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzs7OztFQUkxQixRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDaEMsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUNoQyxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2hDLFFBQVEsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOzs7O0VBSWhDLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDOUIsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOzs7O0VBSTlCLFFBQVEsRUFBRSxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDMUMsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQzFDLFFBQVEsRUFBRSxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQzs7OztFQUkxQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztFQUMvQixRQUFRLEVBQUUsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDL0IsUUFBUSxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDL0IsUUFBUSxFQUFFLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztFQUUvQixRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2pDLFFBQVEsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO0VBQ2pDLFFBQVEsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7RUFDakMsUUFBUSxFQUFFLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7O0VBRWpDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQzs7RUFFdkQsQ0FBQzs7Q0FFRixFQUFFLENBQUM7Ozs7Ozs7QUFPSixTQUFT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LEdBQUcsQ0FBQyxDQUFDLENBQUM7RUFDOUQsS0FBSyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0VBQzlELEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztFQUM5RCxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7RUFDOUQsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0VBQzlELEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztFQUM5RCxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFB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SSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztDQUNuQyxJQUFJLE1BQU0sR0FBRyxLQUFLLEdBQUcsUUFBUSxDQUFDOztDQUU5QixLQUFLLElBQUksQ0FBQyxNQUFNLEdBQUc7O0VBRWxCLFFBQVEsSUFBSSxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxNQUFNLENBQUM7O0VBRTFHLE1BQU0sS0FBSyxNQUFNLEtBQUssQ0FBQyxJQUFJLFFBQVEsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHOztFQUVoRCxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztFQUNqQixNQUFNLEdBQUcsQ0FBQyxDQUFDOztFQUVYOztDQUVELElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDOztDQUVuQixLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksUUFBUSxHQUFHLENBQUMsR0FBRzs7RUFFbEMsRUFBRSxHQUFHLE1BQU0sRUFBRSxFQUFFLFFBQVEsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7O0VBRXBDLE1BQU07OztFQUdOLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUM5RCxFQUFFLEdBQUcsR0FBRyxDQUFDOztFQUVUOztDQUVELEVBQUUsR0FBRyxNQUFNLEVBQUUsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDO0NBQzVCLEVBQUUsR0FBRyxNQUFNLEVBQUUsRUFBRSxRQUFRLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDOztDQUVwQyxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUc7O0VBRXRDLEVBQUUsR0FBRyxNQUFNLEVBQUUsRUFBRSxRQUFRLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDOztFQUVwQyxNQUFNOzs7RUFHTixHQUFHLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7RUFDMUUsRUFBRSxHQUFHLEdBQUcsQ0FBQzs7RUFFVDs7Q0FFRCxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxHQUFHOzs7RUFHeEYsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQztFQUMvQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQztFQUN0RCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQztFQUN0RCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQzs7O0VBR3RELEtBQUssR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQzVCLEtBQUssR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0VBQzVCLEtBQUssR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDOztFQUU1QixFQUFF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
|