text: var Three = (function (exports) {
  	'use strict';
  
  	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 = listenerArray.slice( 0 );
  
  				for ( var i = 0, l = array.length; i < l; i ++ ) {
  
  					array[ i ].call( this, event );
  
  				}
  
  			}
  
  		}
  
  	} );
  
  	var FrontSide = 0;
  	var FlatShading = 1;
  	var NoColors = 0;
  	var NormalBlending = 1;
  	var AddEquation = 100;
  	var SrcAlphaFactor = 204;
  	var OneMinusSrcAlphaFactor = 205;
  	var LessEqualDepth = 3;
  
  	var _Math = {
  
  		DEG2RAD: Math.PI / 180,
  		RAD2DEG: 180 / Math.PI,
  
  		generateUUID: ( function () {
  
  			// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
  
  			var lut = [];
  
  			for ( var i = 0; i < 256; i ++ ) {
  
  				lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );
  
  			}
  
  			return function generateUUID() {
  
  				var d0 = Math.random() * 0xffffffff | 0;
  				var d1 = Math.random() * 0xffffffff | 0;
  				var d2 = Math.random() * 0xffffffff | 0;
  				var d3 = Math.random() * 0xffffffff | 0;
  				var uuid = lut[ d0 & 0xff ] + lut[ d0 >> 8 & 0xff ] + lut[ d0 >> 16 & 0xff ] + lut[ d0 >> 24 & 0xff ] + '-' +
  					lut[ d1 & 0xff ] + lut[ d1 >> 8 & 0xff ] + '-' + lut[ d1 >> 16 & 0x0f | 0x40 ] + lut[ d1 >> 24 & 0xff ] + '-' +
  					lut[ d2 & 0x3f | 0x80 ] + lut[ d2 >> 8 & 0xff ] + '-' + lut[ d2 >> 16 & 0xff ] + lut[ d2 >> 24 & 0xff ] +
  					lut[ d3 & 0xff ] + lut[ d3 >> 8 & 0xff ] + lut[ d3 >> 16 & 0xff ] + lut[ d3 >> 24 & 0xff ];
  
  				// .toUpperCase() here flattens concatenated strings to save heap memory space.
  				return uuid.toUpperCase();
  
  			};
  
  		} )(),
  
  		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;
  
  		},
  
  		ceilPowerOfTwo: function ( value ) {
  
  			return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );
  
  		},
  
  		floorPowerOfTwo: function ( value ) {
  
  			return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );
  
  		}
  
  	};
  
  	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.flatShading = false;
  		this.vertexColors = NoColors; // NoColors, VertexColors, 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.shadowSide = null;
  
  		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.userData = {};
  
  		this.needsUpdate = true;
  
  	}
  
  	Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
  
  		constructor: Material,
  
  		isMaterial: true,
  
  		onBeforeCompile: function () {},
  
  		setValues: function ( values ) {
  
  			if ( values === undefined ) return;
  
  			for ( var key in values ) {
  
  				var newValue = values[ key ];
  
  				if ( newValue === undefined ) {
  
  					console.warn( "Material: '" + key + "' parameter is undefined." );
  					continue;
  
  				}
  
  				// for backward compatability if shading is set in the constructor
  				if ( key === 'shading' ) {
  
  					console.warn( '' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
  					this.flatShading = ( newValue === FlatShading ) ? true : false;
  					continue;
  
  				}
  
  				var currentValue = this[ key ];
  
  				if ( currentValue === undefined ) {
  
  					console.warn( "" + 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 || typeof meta === 'string' );
  
  			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.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
  
  			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.aoMap && this.aoMap.isTexture ) {
  
  				data.aoMap = this.aoMap.toJSON( meta ).uuid;
  				data.aoMapIntensity = this.aoMapIntensity;
  
  			}
  
  			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.flatShading === true ) data.flatShading = this.flatShading;
  			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;
  
  			// rotation (SpriteMaterial)
  			if ( this.rotation !== 0 ) data.rotation = this.rotation;
  
  			if ( this.linewidth !== 1 ) data.linewidth = this.linewidth;
  			if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
  			if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
  			if ( this.scale !== undefined ) data.scale = this.scale;
  
  			if ( this.dithering === true ) data.dithering = true;
  
  			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;
  
  			if ( this.morphTargets === true ) data.morphTargets = true;
  			if ( this.skinning === true ) data.skinning = true;
  
  			if ( this.visible === false ) data.visible = false;
  			if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
  
  			// 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.flatShading = source.flatShading;
  			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.userData = JSON.parse( JSON.stringify( source.userData ) );
  
  			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;
  
  			this.shadowSide = source.shadowSide;
  
  			return this;
  
  		},
  
  		dispose: function () {
  
  			this.dispatchEvent( { type: 'dispose' } );
  
  		}
  
  	} );
  
  	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( '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( '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 );
  
  		},
  
  		applyMatrix3: function ( m ) {
  
  			var x = this.x, y = this.y;
  			var e = m.elements;
  
  			this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];
  			this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];
  
  			return this;
  
  		},
  
  		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 ) {
  
  			// assumes min < max, componentwise
  
  			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.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, 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 );
  
  		},
  
  		manhattanLength: function () {
  
  			return Math.abs( this.x ) + Math.abs( this.y );
  
  		},
  
  		normalize: function () {
  
  			return this.divideScalar( this.length() || 1 );
  
  		},
  
  		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;
  
  		},
  
  		manhattanDistanceTo: function ( v ) {
  
  			return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
  
  		},
  
  		setLength: function ( length ) {
  
  			return this.normalize().multiplyScalar( 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( '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;
  
  		}
  
  	} );
  
  	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, 'rebeccapurple': 0x663399, '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 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( '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( '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 ( gammaFactor ) {
  
  			this.copyGammaToLinear( this, gammaFactor );
  
  			return this;
  
  		},
  
  		convertLinearToGamma: function ( gammaFactor ) {
  
  			this.copyLinearToGamma( this, gammaFactor );
  
  			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 ( target ) {
  
  			// h,s,l ranges are in 0.0 - 1.0
  
  			if ( target === undefined ) {
  
  				console.warn( 'Color: .getHSL() target is now required' );
  				target = { 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;
  
  			}
  
  			target.h = hue;
  			target.s = saturation;
  			target.l = lightness;
  
  			return target;
  
  		},
  
  		getStyle: function () {
  
  			return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
  
  		},
  
  		offsetHSL: function () {
  
  			var hsl = {};
  
  			return function ( h, s, l ) {
  
  				this.getHSL( hsl );
  
  				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();
  
  		}
  
  	} );
  
  	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;
  
  	};
  
  	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;
  
  	};
  
  	exports.MeshPhysicalMaterial = MeshPhysicalMaterial;
  
  	return exports;
  
  }({}));
  